一、反射
通過字符串的形式操作對象相關的屬性。(使用字符串數據類型的變量名來獲取這個變量的值)
Python中的一切事物都是對象(都可以使用反射)
反射類中的變量
反射對象中的變量
反射模板中的變量
反射本文件中的變量
用反射的場景:
input
網絡
文件
#hasattr def hasattr(*args, **kwargs): # real signature unknown """ Return whether the object has an attribute with the given name. This is done by calling getattr(obj, name) and catching AttributeError. """ pass #getattr def getattr(object, name, default=None): # known special case of getattr """ getattr(object, name[, default]) -> value Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y. When a default argument is given, it is returned when the attribute doesn't exist; without it, an exception is raised in that case. """ pass #setattr def setattr(x, y, v): # real signature unknown; restored from __doc__ """ Sets the named attribute on the given object to the specified value. setattr(x, 'y', v) is equivalent to ``x.y = v'' """ pass #delattr def delattr(x, y): # real signature unknown; restored from __doc__ """ Deletes the named attribute from the given object. delattr(x, 'y') is equivalent to ``del x.y'' """ pass
1、getattr()
getattr(變量名:命名空間,字符串:屬於一個命名空間內的變量名)
類名.靜態屬性 getattr(類名,‘靜態屬性’)
類名.類方法() getattr(類名,‘類方法’)()
類名.靜態方法() getattr(類名,‘靜態方法’)()
對象.對象屬性 getattr(對象,‘對象屬性’)
對象.方法() getattr(對象,‘方法’)()
模塊名.方法名
模塊名.類名
模塊名.變量
模塊名.函數
本文件反射 import sys
getattr(sys.modules[__name__],'所有定義在這個文件中的名字')
# 反射類中的變量: 靜態屬性、類方法、靜態方法 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) # oldboy print(Foo.country) # china print(Foo.language) # chiness # 判斷實現 inp = input('>>>') if inp == 'school': print(Foo.school) # oldboy elif inp == 'country': print(Foo.country) # china elif inp == 'language': print(Foo.language) # chiness # 反射實現 while 1: inp = input('>>>') # 輸school,打印oldboy 輸country,打印china 輸language,打印chiness print(getattr(Foo,inp)) # 解析getattr方法 print(getattr(Foo,'school')) # oldboy Foo.class_method() # oldboy print(getattr(Foo,'class_method')) # <bound method Foo.class_method of <class '__main__.Foo'>> getattr(Foo,'class_method')() # oldboy 相當於:Foo.class_method() getattr(Foo,'static_method')() # in staticmethod 相當與:Foo.static_method()
# 反射對象中的變量 class Foo: def __init__(self,name,age): self.name = name self.age = age def eating(self): print('%s is eating' % self.name) alex = Foo('alex',38) print(getattr(alex,'name')) # alex 反射對象屬性 print(getattr(alex,'age')) # 38 getattr(alex,'eating')() # alex is eating 反射對象方法
# 反射模塊中的變量 import os # os就是一個模塊 os.rename('D:\\python_task1.py','D:\\python_task2.py') getattr(os,'rename') # 把python_task1.py改成了python_task2.py getattr(os,'D:\\python_task1.py','D:\\python_task2.py') # 效果同上
# 反射本文件中的變量 a = 1 b = 2 name = 'alex' def qqxing(): print('like eat qqxing') class Foo: pass import sys print(sys.modules['__main__']) # 本文件的命名空間 print(sys.modules['__main__'].a) # 1 print([__name__]) # ['__main__'] 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')() # like eat qqxing print(getattr(sys.modules[__name__],'Foo')) # <class '__main__.Foo'> Foo類的地址 print(getattr(sys.modules[__name__],'Foo')()) # <__main__.Foo object at 0x0072BED0> Foo類對象的地址
2、hasattr()
hasattr(變量名:命名空間,字符串:屬於一個命名空間內的變量名) 成立返回Ture,不成立返回False,一般與getattr搭配使用
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') inp = input('>>>') # 輸入 haha print(getattr(Foo, inp)) # 如果輸入的不存在則報錯 # AttributeError: type object 'Foo' has no attribute 'haha' # 所以要給他定義一個判斷條件 inp = input('>>>') if hasattr(Foo,inp): # 如果輸入的字符串在這個類中,則成立 print(getattr(Foo,inp))
3、setattr()
setattr(名稱空間,變量名,變量值) 更改變量的值
給命名空間的某一個名字設置一個值
# setattr:接受三個參數 命名空間 ‘變量名’ 變量值 class Foo: school = 'oldboy' def func(): print('wahaha') Foo.school = 'OLDBOY' # 直接更改 print(Foo.school) # OLDBOY setattr(Foo,'school','OLDOBY') # 有school這個屬性則更改 print(Foo.school) # OLDBOY print(getattr(Foo,'school')) setattr(Foo,'name','alex') # 沒有name這個屬性則添加 print(Foo.name) # alex print(Foo.__dict__) setattr(Foo,'func',func) # 往類中添加方法,不過一般沒人這么做 Foo.func() #wahaha func() #wahaha print(Foo.__dict__) ''' {'__module__': '__main__', 'Country': 'China', '__dict__': <attribute '__dict__' of 'Foo' objects>,
'__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'func': <function func at 0x00788D68>} '''
4、delattr()
delattr(命名空間,變量)
刪除某一個命名空間中變量對應的值
class Foo: school = 'oldboy' country = 'china' language = 'chiness' def wahaha(self): print('wahaha') def qqxing(self): print('qqxing') del Foo.country # 直接刪除一個屬性 print(Foo.__dict__) delattr(Foo,'school') # 使用delattr刪除一個屬性 print(Foo.__dict__) del Foo.wahaha # 直接刪除一個方法 print(Foo.__dict__) delattr(Foo,'qqxing') # 使用delattr刪除一個方法 print(Foo.__dict__)
二、內置方法
在不是需要程序員定義,本身就存在在類中的方法就是內置方法
內置的方法通常都長這樣:__名字__
各種不同叫法:名字+(雙下方法、魔術方法、內置方法)
所有的雙下方法,都不需要我們直接去調用,都有另外一種自動觸發它的語法
__init__:
不需要我們主動調用,而是在實例化的時候內部自動調用的
__str__ 和 __repr__:
這倆方法的返回值必須是字符串,否則拋出異常。
__str__:
當你打印一個對象的時候 觸發__str__
當你使用%s格式化的時候 觸發__str__
str強轉數據類型的時候 觸發__str__
__repr__:
repr是str的備胎
有__str__的時候執行__str__,沒有實現__str__的時候,執行__repr__
repr(obj)內置函數對應的結果是 __repr__的返回值
當你使用%r格式化的時候 觸發__repr__
class Course: def __init__(self,name,period,price,teacher): self.name = name self.period = period self.price = price self.teacher = teacher def __repr__(self): return 'repr : %s %s %s %s ' % (self.name,self.period,self.price,self.teacher) def __str__(self): return 'str : %s %s %s %s ' % (self.name, self.period, self.price, self.teacher) course_lst = [] python = Course('python','6 month',29800,'alex') course_lst.append(python) linux = Course('linux','5 month',19800,'oldboy') course_lst.append(linux) for id,course in enumerate(course_lst,1): print(id,course) # 1 str : python 6 month 29800 alex # 2 str : linux 5 month 19800 oldboy print('%s %s' % (id,course)) # 效果同上 print(str(course)) # str : python 6 month 29800 alex # str : linux 5 month 19800 oldboy print(repr(course)) # repr : python 6 month 29800 alex # repr : linux 5 month 19800 oldboy print('%r' % course) # 效果同上 # __str__ # 當你打印一個對象的時候 觸發__str__ # 當你使用%s格式化的時候 觸發__str__ # str強轉數據類型的時候 觸發__str__ # __repr__ # repr是str的備胎 # 有__str__的時候執行__str__,沒有實現__str__的時候,執行__repr__ # repr(obj)內置函數對應的結果是 __repr__的返回值 # 當你使用%r格式化的時候 觸發__repr__
#子類與父類的__str__和__repr__觸發順序: class Foo: def __str__(self): return 'Foo.str' def __repr__(self): return 'Foo.repr' class Son(Foo): def __str__(self): return 'Son.str' def __repr__(self): return 'Son.str' obj = Son() print(obj) ''' 當打印子類的對象時: 1、先從子類找__str__ 2、子類中沒有__str__,則到父類找__str__ 3、子類和父類都沒有__str__,則找子類的__repr__ 4、子類和父類都沒有__str__,且子類沒有__repr__,則找父類的__repr__ '''
