反射
反射我們以后會經常用到,這個東西實現了動態的裝配,通過字符串來反射類中的屬性和方法
反射函數
1、hasarttr(obj,name_str)
作用:判斷一個對象obj中是否有對應的name_str字符串的屬性或者方法

class Dog(object): def __init__(self,name): self.name = name def eat(self,food): print("{0} is eating...{1}".format(self.name,food)) d = Dog("shabi") choice = input(">>>:").strip() print(hasattr(d,choice)) #obj中是否有對應的choice字符串的屬性或者方法 #輸出 >>>:name #輸入對象存在屬性 True >>>:eat #輸入對象存在的方法 True
2、getattr(obj,name_str)
作用:根據字符串name_str獲取obj對象中的對應方法的內存地址或者對應屬性的值

class Dog(object): def __init__(self,name): self.name = name def eat(self,food): print("{0} is eating...{1}".format(self.name,food)) d = Dog("shabi") choice = input(">>>:").strip() print(getattr(d,choice)) #choice獲取obj對象中的對應方法的內存地址或者對應屬性的值 #輸出 >>>:name #返回name屬性的值 shabi >>>:eat <bound method Dog.eat of <__main__.Dog object at 0x00000157A129CF28>> #返回eat方法的內存地址
3、setattr(x,y,z)
作用:給obj對象添加一個新屬性或者新方法,setattr(x, 'y', v) is equivalent to ``x.y = v''
①給對象新增一個新方法

def bulk(self): #先定義一個bulk函數 print("{0} is yelling...".format(self.name)) class Dog(object): def __init__(self,name): self.name = name def eat(self,food): print("{0} is eating...{1}".format(self.name,food)) d = Dog("shabi") choice = input(">>>:").strip() setattr(d,choice,bulk) #輸入的是talk,所以又等同於d.talk = bulk #d.talk(d) 直接寫死,用d.talk(d),一般不這么寫 func = getattr(d,choice) #用getattr來獲取 func(d) #輸出 >>>:talk shabi is yelling...
②給對象新增一個屬性

class Dog(object): def __init__(self,name): self.name = name def eat(self,food): print("{0} is eating...{1}".format(self.name,food)) d = Dog("shabi") choice = input(">>>:").strip() setattr(d,choice,22) #輸入的是age,所以又等同於d.age = 22 # print(d.age) 這樣就寫死了,還是用下面一種 print(getattr(d,choice)) #輸出 >>>:age 22
4、delattr(x,y)
作用:刪除obj對象中的屬性或者方法,delattr(x, 'y') is equivalent to ``del x.y''

class Dog(object): def __init__(self,name): self.name = name def eat(self,food): print("{0} is eating...{1}".format(self.name,food)) d = Dog("shabi") choice = input(">>>:").strip() delattr(d,choice) #根據字符串刪除屬性或者方法 print(d.name) print(d.eat) #輸出 >>>:name #刪除屬性name Traceback (most recent call last): print(d.name) AttributeError: 'Dog' object has no attribute 'name' >>>:eat #刪除方法eat Traceback (most recent call last): delattr(d,choice) AttributeError: eat
5、綜合使用hasattr、getattr、setattr

class Dog(object): def __init__(self,name): self.name = name def eat(self,food): print("{0} is eating...{1}".format(self.name,food)) d = Dog("shabi") choice = input(">>>:").strip() if hasattr(d,choice): #判斷d對象中存在屬性和方法 name_value = getattr(d,choice) #獲取屬性值 print(name_value) setattr(d,choice,"hong") #修改屬性值 print(getattr(d,choice)) #重新獲取屬性的值 else: setattr(d,choice,None) #設置不存在的屬性值為None v = getattr(d,choice) print(v) #輸出 >>>:name shabi hong >>>:abc None
創建
前面的隨筆都是關於類的知識,通過類創建對象,那這個類到底是怎么產生的呢?
1、 傳統創建類

class Foo(object): def __init__(self,name): self.name = name f = Foo("shuaigaogao")
f 是通過 Foo 類實例化的對象,其實,不僅 f 是一個對象,Foo類本身也是一個對象,因為在Python中一切事物都是對象,按照一切事物都是對象的理論:obj對象是通過執行Foo類的構造方法創建,那么Foo類對象應該也是通過執行某個類的構造方法創建。
print(type(f)) #輸出:<class '__main__.Foo'> 表示:f 對象由Foo類創建 print(type(Foo)) #輸出:<class 'type'> 表示:Foo類對象由 type 類創建
所以,f 對象是Foo類的一個實例,Foo類對象是 type 類的一個實例,即:Foo類對象 是通過type類的構造方法創建
2 、type創建類
說明: type創建類的格式,類名 = type('類名',(父類,),{'方法名':方法的內存地址})

def func(self): #創建方法 print("hello {0}".format(self.name)) def __init__(self,name): #創建構造方法 self.name = name #通過type創建類,如果是經典類的話則寫成:Foo = type("Foo",(),{"talk":func,"__init__":__init__}) Foo = type("Foo",(object,),{"talk":func,"__init__":__init__}) f = Foo("shuaigaogao") #創建對象 f.talk() #輸出 hello shuaigaogao
總結:類 是由 type 類 實例化產生的
值得注意的是,新式類的寫法,在繼承父類那邊,你繼承一個父類后面就要加一個逗號,加逗號,它就把它當做一個元組,不加逗號,就是一個值了