類屬性和實例屬性


類屬性可以通過dir()函數和__dict__函數進行查詢

dir()函數返回對象屬性的一個名字列表,而__dict__返回的是一個字典,鍵(key)是屬性名。

在看下面的例子

class MyObject():
    def __init__(self):
        self.x = 9      #init函數用於初始化,用於賦值或者添加屬性
    def __le__(self):   #__le__是屬性的一部分
        return 100
    def power(self):
        return self.x*self.x

p = Myobject() dir(Myobject)  #可以看到類作為對象擁有的屬性。
dir(Myobject()) #可以看到實例作為對象擁有的屬性。

print(p.__class__) #實例p所屬類 <class '__main__.MyObject'>
print(p.__class__.__name__)   #MyObject
print(MyObject.__class__) #類Myobject所屬類 <class 'type'>
print(MyObject.__class__.__name__) #type
print(type(MyObject)) #創建類,就是創建一種類型 <class 'type'>
print(type(MyObject())) #實例的類型,是對應的類 <class '__main__.MyObject'>
print(MyObject.__dict__) #可以看到所有的類的特殊屬性(包括模塊名、方法和數值)和存儲值 {'__module__': '__main__', '__init__': <function MyObject.__init__ at 0x005B48A0... ... >
print(MyObject().__dict__) #可以看到實例的屬性,只有數據值 {'x': 9} print(MyObject.__init__) #<function MyObject.__init__ at 0x027848A0> print(MyObject().__init__)  #<bound method MyObject.__init__ of <__main__.MyObject object at 0x02780810>>
print(MyObject().__init__()) #執行以后沒有返回值,所以是None
print(getattr(MyObject(),'__eq__')) #實例的屬性'__eq__’的值 <method-wrapper '__eq__' of MyObject object at 0x02780770> print(MyObject().__eq__) #同上 print(getattr(MyObject(),'x')) #得到屬性 print(MyObject().__le__) #返回屬性值,是一種方法,<bound method MyObject.__le__ of <__main__.MyObject object at 0x02780610>> print(MyObject().__le__()) #返回方法值 print('\d') print(hasattr(MyObject(),'power')) #判斷實例中是否有這個屬性 print(hasattr(MyObject,'power')) #判斷類中有沒有這個屬性 print(MyObject.power) print(MyObject().power)

下面例子可以看清類屬性和實例屬性的區別:

class ObjectCreator():
    count = 0

    def __init__(self):
        ObjectCreator.count +=1
        self.count=8

print(ObjectCreator().count)
print(ObjectCreator.count)

運行結果為:

8
1

 再看一個例子:

class C():
    version = 1.2
    x={2003:'peo2'}

c=C()

print(C.version)    #   1.2
print(c.version)   #實例中沒有version,訪問會失敗,但是Python首先會在實例中搜索version,然后是類,在就是繼承樹種的基類
c.version = 1.3     #建立了一個實例屬性
print(C.version)     #  1.2
print(C.x)
c.x[2004]='SDFS2'   #只是搜索到了C.x,類屬性可以更改,所以這一步沒有建立實例屬性!!!
print(C.x)   #{2003: 'peo2', 2004: 'SDFS2'}
c.x={2004:'SDFS2'}  #建立了實例屬性
print(C.x)  

 

我們定義一個類:

class P1():
    def __init__(self, name):
        self.name = name
        pass
    def change(self):
        self.name = 'xuan'

A=P1('wang')
B=P1('zi')

print(A.name)
A.change()
print(A.name)
print(A.__dict__)

輸出結果

wang
xuan
{'name': 'xuan'}

對象中的方法在沒有實例的情況下不能被調用,只要在有實例的情況才能被調用!

 

我們看一件有意思的事情。

class P1():
    def __init__(self, name):
        self.name = name
        pass

class P2(P1):
    A=P1('wang')   #定義類屬性!!
    B=P1('zi')

i=P2.A     #類屬性
print(i)
print(i.name)
print(P2.__dict__)
print(P2.__dict__['A'])
b=P2.__dict__['A']
print(b)
print(P2.__dict__['A'].name) ##!!!
print(b.name)

輸出結果是:

<__main__.P1 object at 0x01EB0290>

wang   #!!!
{'__module__': '__main__', 'A': <__main__.P1 object at 0x01E50290>, 'B': <__main__.P1 object at 0x01E50390>, '__doc__': None}
<__main__.P1 object at 0x01E50290>
<__main__.P1 object at 0x01E50290>
wang
wang

 我們要用下面,就會報錯

class P1():
    def __init__(self, name):
        self.name = name
        pass

class P2(P1):
    A=P1('wang')
    B=P1('zi')

i=P2.A
print(i)    # 結果為:<__main__.P1 object at 0x00620290>
print(<__main__.P1 object at 0x00620290>.name)

所以我們無法直接利用類屬性中存儲的值,我們可以將它賦值給另一個變量,然后就可以利用這個變量了。

 


免責聲明!

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



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