Python學習筆記(二十三):在運行的時候動態添加屬性和方法


動態語言和靜態語言的區別:

靜態語言:先編譯,後運行;像 C、C++、Java 等;編譯之後什麼樣,運行的時候就是什麼樣;並且靜態語言的類中有哪些屬性,以及哪些方法,在定義類的時候就已經指定好了,在使用類的時候不能修改;

動態語言:不需要編譯,直接運行,並且可以在運行的過程修改代碼,即可以爲類以及對象動態添加屬性或者方法;像 Python、javascript、php 等;

 

動態給對象添加屬性:

# 定義一個類
class Person(object):
    # 初始化方法:爲對象初始化兩個屬性
    def __init__(self, name, age):
        self.name = name
        self.age = age

# 實例化對象
jack = Person("jack", 22)

# 直接獲取對象的屬性
print(jack.name)
print(jack.age)

# 動態給對象添加屬性
jack.addr = "浙江杭州"
print(jack.addr)

 

動態給類添加屬性:

上面給對象添加的屬性只在當前對象有用,如果創建一個新的對象就不能用了;

可以給類添加屬性,累屬性是所有對象都可以共享的;

# 定義一個類
class Person(object):
    # 初始化方法:爲對象初始化兩個屬性
    def __init__(self, name, age):
        self.name = name
        self.age = age

# 動態給類添加屬性
Person.addr = "浙江杭州"

# 實例化對象
jack = Person("jack", 22)
print(jack.name)
print(jack.age)
print(jack.addr)

lucy = Person("lucy", 18)
print(lucy.name)
print(lucy.age)
print(lucy.addr)    # 給類添加的屬性是所有對象共享的

 

動態給對象添加方法:

# 導入 types 模塊
import types

# 定義一個類
class Person(object):
    # 初始化方法
    def __init__(self, name, age):
        self.name = name
        self.age = age

    # 定義一個成員方法
    def eat(self):
        print("=== %s在喫飯 ===" %self.name)

# 定義一個普通方法(注意:接收一個 self 參數)
def sleep(self):
    print("=== %s在睡覺 ===" %self.name)

# 實例化對象
jack = Person("jack", 22);
# 直接通過對象調用成員方法
jack.eat()

# 動態給對象添加方法;
# types.MethodType(sleep, jack):參數1表示普通方法的引用,參數2表示實例對象;
# 該方法表示將 參數1 表示的方法添加到 參數2 表示的對象中;
jack.sleep = types.MethodType(sleep, jack)
jack.sleep()    # 調用新添加的對象方法

 

動態給類添加靜態方法:

# 定義一個類
class Person(object):
    pass

# 定義一個靜態方法(靜態方法可以沒有參數)
@staticmethod
def sleep():
    print("=== 睡覺 ===")

# 動態給類添加靜態方法:
# 即爲 Person 類添加一個屬性 sleep,接收靜態方法 sleep() 的引用
Person.sleep = sleep
Person.sleep()  # 調用類的靜態方法

# 注意:靜態方法只能添加給類,而不能添加給對象,下面的做法是錯誤的:
jack = Person("jack", 22)
jack.sleep = sleep  # 動態爲對象添加靜態方法:
jack.sleep()

 

動態給類添加類方法:

# 定義一個類
class Person(object):
    pass

# 定義一個類方法(類方法需要接收一個 cls 參數)
@classmethod
def sleep(cls):
    print("=== 睡覺 ===")

# 動態給類添加類方法:
# 即爲 Person 類添加一個屬性 sleep,接收類方法 sleep() 的引用
Person.sleep = sleep
Person.sleep()  # 調用類方法

# 注意:類方法也是隻能添加給類,而不能添加給對象,下面的做法是錯誤的:
jack = Person("jack", 22)
jack.sleep = sleep  # 動態爲對象添加類方法:
jack.sleep()

 

__slots__ 變量的用法:

在上面我們已經知道,動態語言可以在運行的過程中動態添加屬性和方法,那如果我想限制只允許爲對象添加 name 和 age 屬性,應該怎麼做呢?

爲了達到限制的目的,python 允許在定義 class 的時候,定義一個特殊的 __slots__ 變量,來限制該 class 的實例能夠添加的屬性;

# 定義一個類
class Person(object):
    # 限制只能爲 Person 實例添加 name 和 age 屬性
    __slots__ = ("name", "age")

# 實例化對象
jack = Person()

# 只能爲對象添加 name 和 age 屬性
jack.name = "jack"
jack.age = 22

print(jack.name, jack.age)

# 如果爲對象添加其他屬性,就會報錯
jack.addr = "浙江杭州"
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章