python--類的反射、類的創建


反射

反射我們以后會經常用到,這個東西實現了動態的裝配,通過字符串來反射類中的屬性和方法

反射函數

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
View Code

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方法的內存地址
View Code

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...
View Code

②給對象新增一個屬性

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
View Code

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
View Code

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
View Code

 

 

創建

前面的隨筆都是關於類的知識,通過類創建對象,那這個類到底是怎么產生的呢?

1、 傳統創建類

class Foo(object):
    def __init__(self,name):
        self.name = name
  
f = Foo("shuaigaogao")
View Code

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  
View Code

總結:類 是由 type 類 實例化產生的

值得注意的是,新式類的寫法,在繼承父類那邊,你繼承一個父類后面就要加一個逗號,加逗號,它就把它當做一個元組,不加逗號,就是一個值了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM