動態語言和靜態語言的區別:
靜態語言:先編譯,後運行;像 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 = "浙江杭州"