反射

反射:用带字符串类型的名字 去获取 变量

一、类中的反射

在学反射以前,我们也学习了一种方法,可以获取字符串中的变量 eval()但是安全性不高

name = "duke"
eval("print(name)")  #duke

因为前面介绍的是类,因此我们便已类来介绍反射的使用方法;反射 有四个函数 getatter()获取变量;hasatter()查询字符串中变量是否存在;seratter(),更改字符串中变量的值;delatter 删除字符串中的属性值。前两者使用相当广泛,且经常搭配使用;而后两者的使用场景较少,且有一定的安全隐患。

使用方法 :getatter(对象\类,"string")  反射对象的方法,如果实在类的普通方法的内部是用,self即为函数对象

class A:
    def func(self):
        print("in func")

a = A()
a.name = "alex"  #给a对象添加一个数据属性name
#反射对象的属性 getatter(对象,属性名的字符串形式)
ret = getattr(a,"name") #通过变量名的字符串的形式取到的值
print(ret)
print(a.__dict__) #{'name': 'alex'}该方法只存数据属性,不存方法
# 变量名 =input(">>>>:").strip()
# print(getattr(a,变量名))
#反射对象的方法 getatter(对象,属性方法的字符串形式) 拿到一个绑定方法 +()执行
ret = getattr(a,"func") #返回该方法的内存地址
ret()#加括号便能执行,若该方法需要传参,直接在()内按照函数传参的方式传入即可

反射类:在class 中 还有两种方法 @staticmethod静态方法 @classmethod类方法  同样也有类变量

反射类的属性
class A:
    price = 20
    @classmethod
    def func(cls,name):
        print("%s in func" % name)
    @staticmethod
    def dunc1():
        print("静态方法")
#反射类的数据获取
print(getattr(A,"price")) #20
#反射类的方法 classmethod staticmethod(这两种方法完全可以由类名调用)
getattr(A,"func")("duke") #duke in func
getattr(A,"dunc1")() #静态方法

我们在学习的过程不仅类与对象可以采用x.x 的当时执行;模块也可以使用这种方法;,同样模块也可以使用反射

模块反射:也有数据和方法两种,使用方法同上

使用模块如下:模块名 my_moudle.py

day = "Monday" 
def refraction_test():
    print("test successful")
class C:
    c= 255
    def fun(self):
        print("模块中的普通方法类")
    @classmethod
    def fun2(cls):
        print("模块中的类方法")

测试如下:

#模块里面的反射
import my_moudle
# print(my_moudle.day)
print(getattr(my_moudle,"day"))#静态方法
#反射模块的方法 同对象与类
getattr(my_moudle,"refraction_test")()#test successful
#反射模块的类
#获得对象如果加括号 则等于创建了一个对象
refraction_object = getattr(my_moudle,"C")()
refraction_object.fun() #模块中的普通方法类
print(getattr(refraction_object,"c")) #255
#未加括号 则相当于 把那个类给借调过来了
refraction_class = getattr(my_moudle,"C")
print(refraction_class.c) #255
getattr(refraction_class,"fun2")() #模块中的类方法

一个py文件就是一个模块,能够在导入的模块中使用反射,那能不能在当前文件中使用反射,当然是可以,首先我们需要或得到当前文件对应的模块名。

import sys

for i in sys.modules:
    print("%-20s%s" %(i,sys.modules[i]))

"""
sys                           <module 'sys' (built-in)>
builtins                      <module 'builtins' (built-in)>
_frozen_importlib             <module '_frozen_importlib' (frozen)>
_imp                          <module '_imp' (built-in)>
_thread                       <module '_thread' (built-in)>
_warnings                     <module '_warnings' (built-in)>
_weakref                      <module '_weakref' (built-in)>
zipimport                     <module 'zipimport' (built-in)>
_frozen_importlib_external    <module '_frozen_importlib_external' (frozen)>
_io                           <module 'io' (built-in)>
marshal                       <module 'marshal' (built-in)>
nt                            <module 'nt' (built-in)>
winreg                        <module 'winreg' (built-in)>
encodings                     <module 'encodings' from 'F:\\python\\lib\\encodings\\__init__.py'>
codecs                        <module 'codecs' from 'F:\\python\\lib\\codecs.py'>
_codecs                       <module '_codecs' (built-in)>
encodings.aliases             <module 'encodings.aliases' from 'F:\\python\\lib\\encodings\\aliases.py'>
encodings.utf_8               <module 'encodings.utf_8' from 'F:\\python\\lib\\encodings\\utf_8.py'>
_signal                       <module '_signal' (built-in)>
__main__                      <module '__main__' from 'F:/code/文件夹 类的反射/反射.py'>
encodings.latin_1             <module 'encodings.latin_1' from 'F:\\python\\lib\\encodings\\latin_1.py'>
io                            <module 'io' from 'F:\\python\\lib\\io.py'>
abc                           <module 'abc' from 'F:\\python\\lib\\abc.py'>
_abc                          <module '_abc' (built-in)>
site                          <module 'site' from 'F:\\python\\lib\\site.py'>
os                            <module 'os' from 'F:\\python\\lib\\os.py'>
stat                          <module 'stat' from 'F:\\python\\lib\\stat.py'>
_stat                         <module '_stat' (built-in)>
ntpath                        <module 'ntpath' from 'F:\\python\\lib\\ntpath.py'>
genericpath                   <module 'genericpath' from 'F:\\python\\lib\\genericpath.py'>
os.path                       <module 'ntpath' from 'F:\\python\\lib\\ntpath.py'>
_collections_abc              <module '_collections_abc' from 'F:\\python\\lib\\_collections_abc.py'>
_sitebuiltins                 <module '_sitebuiltins' from 'F:\\python\\lib\\_sitebuiltins.py'>
sitecustomize                 <module 'sitecustomize' from 'F:\\pycharm\\PyCharm 2018.2.5\\helpers\\pycharm_matplotlib_backend\\sitecustomize.py'>
my_moudle                     <module 'my_moudle' from 'F:\\code\\文件夹 类的反射\\my_moudle.py'>
time                          <module 'time' (built-in)>
"""

从sys.moudles 中我们可以得知__main__ 对应的模块名为:"__main__"

import sys
year = 2018
def test():
    print("test")
import sys
print(sys.modules["__main__"]) #表示自己模块 <module '__main__' from 'F:/code/文件夹 类的反射/反射.py'>
print(getattr(sys.modules["__main__"],"year")) #2018
getattr(sys.modules["__main__"],"test")() #test

当然,我们也知道,当被导入使用时,__main__ 就不会表示原先的py文件,表示便会时当时的执行文件,这是就需要用到__name__这个方法了,当在本文件运行=__main__,不再本文件运行时,则不等于__main__=模块名,因此上面那个式子,应该改进一下:

print(getattr(sys.modules[__name__],"year")) #2018

同样,若反射能在自定义模块中执行,自然能在内置模块中使用,以time模块为例

import time
print(getattr(time,"time")()) #1542720516.2940655

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值