給Python的類和對象動態增加屬性和方法


通常我們會將編程語言分為靜態和動態。靜態語言的變量是在內存中的有類型的且不可變化的,除非強制轉換它的類型;動態語言的變量是指向內存中的標簽或者名稱,其類型在代碼運行過程中會根據實際的值而定。Python就是典型的動態語言。

動態添加屬性

當類或者對象的屬性在需要增加的時候,對於不方便修改源碼的情況下,我們可以選擇動態的對其添加屬性。

動態給對象添加屬性

對象屬性只在當前對象生效,在其他對象中是無法調用的。

定義一個類:

class Student(object):

    def __init__(self,name,age):
        self.name=name
        self.age=age

執行:(給實例添加數學成績屬性並且初始化)

>>> from payhlib import Student 
>>> s=Student('phyger',18) 
>>> s.name
'phyger'
>>> s.age
18
>>> s.math_score=100
>>> s.math_score    
100
>>> ss=Student('xiaopang',28)
>>> ss.name
'xiaopang'
>>> ss.age 
28
>>> ss.math_score
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'math_score'
>>>

動態給類添加屬性

類屬性在其所有的對象中都生效。

執行:(默認所有對象的音樂成績為60,當然你也可以對其進行修改)

>>> from payhlib import Student
>>> Student.music_score=60
>>> s1=Student('phyger',19) 
>>> s1.name
'phyger'
>>> s1.age
19
>>> s1.music_score
60
>>> s2=Student('xiaopang',29)
>>> s2.music_score
60
>>>

動態添加方法

當類或者對象的方法在需要增加的時候,對於不方便修改源碼的情況下,我們可以選擇動態的對其添加方法。

動態給對象添加方法

給對象添加的方法只綁定在當前對象上,不對其他對象生效,而且需要傳入self參數。

執行:(通過types.MethodType方法給a對象綁定sayhi方法)

>>> from payhlib import Student
>>> a=Student('phyger',17) 
>>> def sayhi(self):
...     print('hi...')
... 
>>> a.sayhi()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'sayhi'
>>> import types  
>>> a.sayhi=types.MethodType(sayhi,a)
>>> a.sayhi()
hi...
>>> b=Student('xiaopang',27) 
>>> b.sayhi()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'sayhi'
>>>

動態給類添加方法(類方法和靜態方法)

給類添加的方法對它的所有對象都生效,添加類方法需要傳入self參數,添加靜態方法則不需要。

執行:(給類添加靜態方法)

>>> from payhlib import Student                 
>>> stu = Student('phyger',16)
>>> @staticmethod
... def staticHi():
...     print('staticHi...')
... 
>>> Student.hi=staticHi  
>>> stu.hi
<function staticHi at 0x000001CB617F13A8>
>>> stu.hi()
staticHi...
>>>

執行:(給類添加類方法)

因為類方法只能使用類變量,所以我們增加一個類變量home

class Student(object):
    home='china'

    def __init__(self,name,age):
        self.name=name
        self.age=age
>>> from payhlib import Student
>>> stu = Student('phyger',17)  
>>> @classmethod        
... def classHi(self):  
...     print(self.home)
... 
>>> Student.chi=classHi
>>> stu.chi()
china
>>>

限制給類或對象添加的屬性

假如我們只希望類或者對象有name,age,score三個屬性,我們可以借助__slots__來做,而且無法添加其他屬性。

修改類:

class Student(object):
    home='china'
    __slots__=('name','age','score')   #init中變量必須在__slots__中

    def __init__(self,name,age):
        self.name=name
        self.age=age

執行:

>>> from payhlib import Student
>>> st = Student('phyger',16)
>>> st.name 
'phyger'
>>> st.age 
16
>>> st.score
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: score
>>> st.score =100
>>> st.score      
100
>>> st.phone='123'      #無法添加phone屬性
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'phone'
>>>

多總結幾點:

  • 類屬性是read-only的
  • 靜態方法無法使用類變量
  • 類方法只能使用類變量,不能使用初始化變量
  • __slots__數據類型為元組
  • __slots__只對當前類生效,對其子類不生效


免責聲明!

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



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