反射
是什么
反射,使用字符串数据类型的变量名来获取这个变量的值
why 为什么 三个场景
a = 1 b = 2 name = ‘xiao’
1.input:用户输入的如果是a,那么就打印1,如果输入的是b就打印2,如果输入的是name,就打印xiao
2.文件:从文件中读出的字符串,想转换成变量的名字
3.网络:将网络传输的字符串转化成变量的名字
where 在哪儿用
class Foo: School = 'oldboy' Country = 'China' language = 'Chiness' @classmethod def class_method(cls): print(cls.School) @staticmethod def static_method(): print('in staticmethod') def wahaha(self): print('wahaha') print(Foo.School) print(Foo.Country) print(Foo.language) # 反射实现 while True: inp = input('>>>') if hasattr(Foo,inp): #判断是否在类中 print(getattr(Foo,inp)) getattr(Foo,'School') # Foo.School print(Foo.class_method) print(getattr(Foo,'class_method')) getattr(Foo,'class_method')() # Foo.class_method() getattr(Foo,'static_method')() # Foo.static_method() getattr(Foo,'wahaha')(1) # Foo.wahaha(1) print(hasattr(Foo,'wahaha')) print(hasattr(Foo,'shuangwaiwai'))
hasattr方法
hasattr 判断
getattr方法
getattr(变量名:命名空间,字符串:属于一个命名空间内的变量名)
反射模块中的变量
import os getattr(os,'rename')('娃哈哈','爽歪歪') #os.rename('娃哈哈','爽歪歪')
反射本文件中的变量
a = 1 b = 2 name = 'vip' def thank(): print('thank') class Foo:pass import sys print(sys.modules[__name__]) # 反射本文件中的变量 固定的使用这个命名空间 print(getattr(sys.modules[__name__],'a')) print(getattr(sys.modules[__name__],'b')) print(getattr(sys.modules[__name__],'name')) getattr(sys.modules[__name__],'thank')() print(getattr(sys.modules[__name__],'Foo')) #<class '__main__.Foo'> obj = getattr(sys.modules[__name__],'Foo')() #<__main__.Foo object at 0x0000021CC9037668> print(obj)
setattr
class Foo: country = 'China' def func(); print('think') setattr(Foo,'School','study') #Foo.School = 'study' # 接受三个参数 命名空间 ‘变量名’ 变量值 print(Foo.__dict__) print(getattr(Foo,'School')) print(Foo.School) setattr(Foo,'func',func) # 一般没人往空间中添加函数 print(Foo.__dict__) print(Foo.func)
内置方法
在不是需要程序员定义,本身就存在在类中的方法就是内置方法。
内置方法通常长这样: __ 名字__
名字: 双下方法、魔术方法、内置方法
__ init__
不需要我们主动调用,而是在实例化的时候内部自动调用的
所有的双下方法,都不需要我们直接去调用,都有另外一种自动触发它的语法
__ str __ __ repr__
__ str__
1.当你打印一个对象的时候,触发__ str__
2.当你使用%s格式化的时候,触发 __ str__
3.str强转数据类型的时候,触发 __ str__
__ repr__
1.repr是str的备胎
2.有__str__的时候执行__str__,没有实现__str__的时候,执行__repr__
3.repr(obj)内置函数对应的结果是__repr__的返回值
4.当你使用%r格式化 时候 触发__repr__
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('python','6 month',29800,'boss jin') course_lst.append(python) linux = Course('linux','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)
父类与子类 __ str__ __ repr__
class Foo: def __str__(self): return 'Foo.str' def __repr__(self): return 'Foo.repr' class Son(Foo): pass def __str__(self): return 'Son.str' def __repr__(self): return 'Son.repr' s1 = Son() print(s1)
总结:先__str__,如果没有去父类找__str__,还没有就找子类的__repr__,最后没有就找父类的__repr__。