反射
反射是什么
反射:使用字符串数据类型的变量名 来获取这个变量的值
在哪用:
- input :用户输入的如果是a 就打印1 如果输入的是B 就打印2 如果输入的是name 就打印‘yeyeye’
a,b,c=1,2,'yeyeye' print(input('输入内容:'))
- 文件 :从文件中读出的字符串 想转换成变量的名字
- 网络: 将网络传输的字符串转换成变量的名字
-
反射类中的变量
反射对象中的变量
反射模块中的变量
反射本文件中的变量
怎么用:
class Foo: name = 'yeyeye' Country = 'China' language = 'Chinese' @classmethod def class_method(cls): print(cls.name) @staticmethod def static_method(): print('in staticmethod') def wahaha(self): print('wahaha') # 判断实现 # while True: # inp = input('>>>') # if inp == 'name':print(Foo.name) # elif inp == 'Country':print(Foo.Country) # elif inp == 'language':print(Foo.language) # 反射实现 while True: inp = input('输入内容:') print(getattr(Foo,inp))
反射模块中的方法:
import os # os就是一个模块 # os.rename('文件路径及文件名','新的文件路径和文件名') getattr(os,'rename')('文件路径及文件名','新的文件路径和文件名') #用字符串的形式执行rename
反射文本中的变量:
a = 1 b = 2 name = 'alex' def qqxing(): print('qqxing') class Foo:pass
import sys print(sys.modules[__name__]) # 反射当前文件中的变量 固定的使用这个命名空间 print(getattr(sys.modules[__name__],'a')) #1 print(getattr(sys.modules[__name__],'b')) #2 print(getattr(sys.modules[__name__],'name')) #alex getattr(sys.modules[__name__],'qqxing')() #qqxing print(getattr(sys.modules[__name__],'Foo')) #<class '__main__.Foo'> obj = getattr(sys.modules[__name__],'Foo')() print(obj) #<__main__.Foo object at 0x000001C444276898>
getattr方法:
用于返回一个对象属性值。
获取对象object的属性或者方法,如果存在打印出来,如果不存在,打印出默认值,默认值可选。
需要注意的是,如果是返回的对象的方法,返回的是方法的内存地址,如果需要运行这个方法,
可以在后面添加一对括号。
class A(object): bar = 1 a = A() getattr(a, 'bar') # 获取属性 bar 值 1 getattr(a, 'bar2') # 属性 bar2 不存在,触发异常 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'A' object has no attribute 'bar2' getattr(a, 'bar2', 3) # 属性 bar2 不存在,但设置了默认值 3
hasattr方法:
用于判断对象是否包含对应的属性 如果对象有该属性返回 True,否则返回 False。
class A(): name = 'python' def func(self): return 'A()类的方法func()' hasattr(A, 'name') #True hasattr(A, 'age') #False hasattr(A, 'func') #True
setattr方法:
给对象的属性赋值,若属性不存在,先创建再赋值。
class test(): name="yeyeye" def run(self): return "HelloWord" t=test() hasattr(t, "age") #判断属性是否存在 #False setattr(t, "age", "18") #为属相赋值,并没有返回值 hasattr(t, "age") #属性存在了 #True
def func(): print('qqxing') Foo.Name = 'yeyeye' print(Foo.__dict__) print(getattr(Foo,'Name')) setattr(Foo,'Name','wanwan') # 接受三个参数(命名空间,‘变量名’,变量值) print(Foo.Name)
delattr方法:
用来删除指定对象的指定名称的属性,和setattr函数作用相反。
class Foo: Country = 'China' def func(): print('qqxing') Foo.Name = 'yeyeye' del Foo.Country #常规 print(Foo.__dict__) delattr(Foo,'Country') #反射删除 print(Foo.__dict__)
内置方法:
在不是需要自己定义 本身就存在类中的方法就是内置方法
内置方法通常长这样: __方法名__
昵称: 双下方法 魔术方法 内置方法
比如:__init__
不需要我们主动调用 而是咋实例化的时候 内部自动调用的
所有的双下方法 都不需要我们直接无调用 都有另外一种自动触发它的语法
__str__
当你打印一个对象的时候 触发__str__
当你使用%s格式化的时候 触发__str__
str强转数据类型的时候 触发__str__
__repr__
repr是str的备胎
有__str__的时候执行__str__,没有实现__str__的时候,执行__repr__
repr(obj)内置函数对应的结果是 __repr__的返回值
当你使用%r格式化的时候 触发__repr__
__repr__和__str__这两个方法都是用于显示的,__str__是面向用户的,而__repr__面向程序员。
-
打印操作会首先尝试__str__和str内置函数(print运行的内部等价形式),它通常应该返回一个友好的显示。
-
__repr__用于所有其他的环境中:用于交互模式下提示回应以及repr函数,如果没有使用__str__,会使用print和str。它通常应该返回一个编码字符串,可以用来重新创建对象,或者给开发者详细的显示。
class Course: def __init__(self,name,period,price,teacher): self.name= name self.period = period self.price = price self.teacher = teacher def __str__(self): return 'str : %s %s %s %s' % (self.name, self.period, self.price, self.teacher) def __repr__(self): return 'repr : %s %s %s %s' % (self.name, self.period, self.price, self.teacher) course_lst = [] python = Course('如何快速花光一亿','6 month',29800,'boss jin') course_lst.append(python) linux = Course('如何与傻逼相处','5 month',25800,'oldboy') course_lst.append(linux) for id,course in enumerate(course_lst,1): print('%s %s %s %s %s'%(id,course.name,course.period,course.price,course.teacher)) print(id,course) print('%s %s'%(id,course)) print(str(course)) print(repr(course)) print('%r'%course)
class Test: def __init__(self, value='hello, world!'): self.data = value t = Test() print (t)# <__main__.Test object at 0x7fa91c307190> # 看到了么?上面打印类对象并不是很友好,显示的是对象的内存地址 # 下面我们重构下该类的__repr__以及__str__,看看它们俩有啥区别 # 重构__repr__ class TestRepr(Test): def __repr__(self): return 'TestRepr(%s)' % self.data tr = TestRepr() print(tr)# TestRepr(hello, world!) # 重构__repr__方法后,不管直接输出对象还是通过print打印的信息都按我们__repr__方法中定义的格式进行显示了 # 重构__str__ class TestStr(Test): def __str__(self): return '[Value: %s]' % self.data ts = TestStr() print(ts) # [Value: hello, world!] # 你会发现,直接输出对象ts时并没有按我们__str__方法中定义的格式进行输出,而用print输出的信息却改变了