動態(tài)編程語言是高級程序設計語言的一個類別,在計算機科學領域已被廣泛應用。它是一類 在運行時可以改變其結(jié)構(gòu)的語言 :例如新的函數(shù)鹦赎、對象、甚至代碼可以被引進误堡,已有的函數(shù)可以被刪除或是其他結(jié)構(gòu)上的變化古话。動態(tài)語言目前非常具有活力。例如JavaScript便是一個動態(tài)語言锁施,除此之外如 PHP 陪踩、 Ruby 、 Python 等也都屬于動態(tài)語言悉抵,而 C 肩狂、 C++ 等語言則不屬于動態(tài)語言。
運行過程中給對象添加屬性:
class Dog(object):
def __init__(self, name, color):
self.name = name
self.color = color
d1 = Dog('旺財', '黑色')
print(d1.name)
print(d1.color)
d1.brand = '哈士奇'
#print(dir(d1)) 多了brand屬性
print(d1.brand)
結(jié)果如下:
在定義的Dog類中并沒有brand姥饰,但我們得到并打印出了這個屬性傻谁。如果我們再定義一個對象,比如d2列粪,調(diào)用d2.brand审磁,運行就會報錯谈飒,也就是我們只對d1屬性添加了brand屬性,而d2并沒有依然是Dog類中的屬性态蒂,如何在運行過程中將屬性添加到類中:
class Dog(object):
def __init__(self, name, color):
self.name = name
self.color = color
Dog.brand = '京巴'
d1 = Dog('旺財', '黑色')
print(d1.name)
print(d1.color)
print(d1.brand)
print('*'*15)
d2 = Dog('小強', '白色')
print(d2.name)
print(d2.color)
print(d2.brand)
結(jié)果如下:
可以看到杭措,通過Dog.brand = ‘京巴’,為類添加了一個brand屬性钾恢,默認值是’京巴’手素。不論是d1還是d2調(diào)用brand都會有結(jié)果。除了在運行過程中給類添加屬性瘩蚪,還可以在運行過程中給類添加方法泉懦。
class Dog(object):
def __init__(self, name, color):
self.name = name
self.color = color
def eat(self):
print('%s在吃。募舟。祠斧。' % self.name)
Dog.eat = eat
d1 = Dog('旺財', '黑色')
d1.eat()
結(jié)果如下:
既然可以給類添加方法闻察,也就可以給對象添加方法拱礁。
import types
class Dog(object):
def __init__(self, name, color):
self.name = name
self.color = color
def eat(self):
print('%s在吃。辕漂。呢灶。' % self.name)
d1 = Dog('旺財', '黑色')
d1.eat = types.MethodType(eat, d1)
d1.eat()
結(jié)果如下:
這僅為d1這個對象添加了eat這個方法,如果創(chuàng)建一個對象d2钉嘹,d2.eat()就會報錯鸯乃。
既然可以在運行過程中添加屬性和方法,那就可以在運行過程中刪除屬性和方法跋涣。
del 對象.屬性
也可以用delattr(對象名缨睡,’屬性’)
即可刪除對象的屬性
class Dog(object):
def __init__(self, name, color):
self.name = name
self.color = color
d1 = Dog('旺財', '黑色')
print(d1.name)
#del d1.name
delattr(d1, 'name')
print(d1.name)
結(jié)果如下:
刪除d1.name后再打印d1.name就會報錯。
通過以上例子可以得出一個結(jié)論:相對于動態(tài)語言陈辱,靜態(tài)語言具有嚴謹性奖年!所以,玩動態(tài)語言的時候沛贪,小心動態(tài)的坑陋守!
那么怎么避免這種情況呢? 請使用slots
現(xiàn)在我們終于明白了利赋,動態(tài)語言與靜態(tài)語言的不同
動態(tài)語言:可以在運行的過程中水评,修改代碼
靜態(tài)語言:編譯時已經(jīng)確定好代碼,運行過程中不能修改
如果我們想要限制實例的屬性怎么辦媚送?比如中燥,只允許對Person實例添加name和age屬性。只能限定實例對象的添加屬性和方法塘偎,為了達到限制的目的疗涉,Python允許在定義class的時候幽纷,定義一個特殊的slots變量,來限制該class實例能添加的屬性:
class Dog:
__slots__ = ('name', 'brand')
def __init__(self, name, brand):
self.name = name
self.brand = brand
wangcai = Dog('旺財', '哈士奇')
print(wangcai.name)
print(wangcai.brand)
wangcai.color = '白色'
print(wangcai.color)
結(jié)果如下:
使用slots要注意博敬,slots定義的屬性僅對當前類實例起作用友浸,對繼承的子類是不起作用的。