Python是一門動態的語言
1、什麼是動態語言
動態編程語言是高級程序設計語言的一個類別,他是一類在運行時可以改變其結構的語言:例如新的函數、對象、甚至代碼可以被改進,已有的函數可以被刪除或者是其他的結構上的變化。動態語言有:javascript、php、Ruby、Python等都是動態語言。
2、運行過程中給對象綁定(添加)屬性
In [1]: class Person(object):
...: def __init__(self, new_name):
...: self.name = new_name
...:
In [2]: wang = Person("老王")
上面的代碼中,我們定義了一個Person類,在類中有一個初始屬性name,如果我們想添加age屬性呢?
In [3]: wang.age = 18
In [4]: print(wang.name)
老王
In [5]: print(wang.age)
18
要給實例對象添加實例屬性,可以直接對象名.屬性 = 值
3、運行的過程中給類綁定(添加)屬性
上面我們在運行過程中給實例對象添加了屬性,那麼我們再創建一個實例對象,能不能直接去調用age屬性呢?
In [6]: li = Person("老李")
In [7]: li.age
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-7-683a5751e9b0> in <module>()
----> 1 li.age
AttributeError: 'Person' object has no attribute 'age'
我們發現在實例對象li中沒有age這個屬性,我麼想給所有的Person的實例都加上age屬性怎麼辦?答案就是直接給Person添加屬性:
In [8]: Person.age = 0
In [9]: li = Person("老李")
In [10]: li.age
Out[10]: 0
4、運行過程中給類添加方法
首先我們定義一個函數:
def print_msg(self):
print("姓名:%s,年齡:%d" % (self.name, self.age))
上面我們直接給對象綁定屬性,直接實例對象.屬性 = 值
,那給實例對象添加方法呢?可不可以直接實例對象.方法名 = 方法名
呢?
wang.print_mag = print_msg
# 會直接產生異常 AttributeError: 'Person' object has no attribute 'print_msg'
# 是因爲在調print_msg方法的時候,self並沒有參數
那麼我們怎麼做才能添加呢?
import types
wang.print_msg = types.MethodType(print_msg, wang)
5、添加類方法
@classmethod
def p_class(cls):
cls.num = 100
# 動態添加類方法
Person.p_class = p_class
Person.p_class()
print(Person.num)
6、添加靜態方法
@staticmethod
def run():
print("-----------run----------")
# 動態添加靜態方法
Person.run = run
li.run()
7、__slots__
動態語言:可以再運行過程中,修改代碼
靜態語言:編譯時已經確定好代碼,運行過程中不能修改
如果我們想要限制實例的屬性,怎麼辦?
比如,只允許對Person添加name、age、sex屬性。
在Python中爲了達到限制的目的,Python是允許在定義class的時候,定義一個特殊的
__slots__
,來限制class實例能添加的屬性In [12]: class Person(object): ....: __slots__ = ("name", "age", "sex") ....: In [13]: p = Person() In [14]: p.name = "老王" In [15]: p.age = 18 In [16]: p.sex = "男" In [17]: p.address = "隔壁" <hr /> AttributeError Traceback (most recent call last) <ipython-input-17-c00075f138fc> in <module>() ----> 1 p.address = "隔壁" AttributeError: 'Person' object has no attribute 'address'
注意點:
- 使用
__slots__
要注意,__slots__
定義的屬性僅對當前類實例起作用,對繼承的子類是不起作用的