Python動態語言的特性

1、動態語言相關概念

1.1 動態語言

  • 在運行時代碼能夠根據某些條件改變自身結構
  • 能夠在運行時引進新的函數、對象、甚至代碼,能夠刪除已有的函數等其餘結構上的變化
  • 常見的動態語言:Object-C、C#、JavaScript、PHP、Python、Erlang

1.2 動態類型語言

  • 在運行期間檢查數據類型的語言
  • 數據類型不是在編譯階段決定的,而是把類型綁定延後到了運行階段
  • 常見的動態類型語言:Python、Ruby、Erlang、JavaScript、swift、PHP、Perl

1.3 強類型語言

  • 一旦一個變量被指定了某個數據類型,若是不通過強制類型轉換,那麼它就永遠是這個數據類型
  • 常見的強類型語言:Java、C#、Python、Object-C、Ruby

Python是動態語言,動態類型語言,也是強類型語言。因此Python能夠在運行時改變自身結構,動態添加/刪除屬性和方法。接下來將介紹Python如何動態添加屬性和方法。swift

2、動態添加屬性

 2.1 添加對象屬性

class Obj(object):
    def __init__(self):
        self.name = '張亞飛'


obj = Obj()
obj.age = 23
print(obj.age)
obj2 = Obj()
print(obj2.age)
由以上代碼可知,Obj類有兩個屬性:name和age。經過[對象名.屬性名]給類對象obj動態添加了對象屬性addr,而Obj的另外一個類對象obj2卻不能調用這個屬性。 注:經過對象名添加的對象屬性,只有這個對象能使用

2.2 添加類屬性

Obj.score = 100
print(obj.score)
print(obj2.score)
  由以上代碼可知,經過[類名.屬性名]給類Obj動態添加了類屬性addr,Obj的類對象obj和obj2都能調用這個屬性
    注:經過類名添加的類屬性,這個類的全部對象都能使用
 

3、動態添加方法

類中有三種方法,實例方法,靜態方法和類方法,三種方法的區別以下:
實例方法:須要綁定要一個對象上,第一個參數默認使用self,會把對象做爲第一個參數傳遞進來
靜態方法:使用裝飾器@staticmethod進行定義,類和對象均可以調用,不須要默認參數
類方法:使用裝飾器@classmethod進行定義,類和對象均可以調用,第一個參數默認使用cls,會把類做爲第一個參數傳遞進來函數

from types import MethodType


class Obj(object):
    # __slots__ = ('name', 'age')

    def __init__(self):
        self.name = '張亞飛'


def set_score(self, score):
    self.score = score


@staticmethod
def static_func():
    print('static_func')


@classmethod
def class_func(cls):
    print('class_method')
「「「
類中有三種方法,實例方法,靜態方法和類方法,三種方法的區別以下:
實例方法:須要綁定要一個對象上,第一個參數默認使用self,會把對象做爲第一個參數傳遞進來
靜態方法:使用裝飾器@staticmethod進行定義,類和對象均可以調用,不須要默認參數
類方法:使用裝飾器@classmethod進行定義,類和對象均可以調用,第一個參數默認使用cls,會把類做爲第一個參數傳遞進來
」」」
# 動態添加實例方法
obj = Obj()
obj.set_score = MethodType(set_score, obj) obj.set_score(99) print(obj.score) # 99
obj2.set_score(99) #
AttributeError: 'Obj' object has no attribute 'set_score'
"""
由以上代碼可知,Obj類有一個方法:eat()方法。經過[types.MethodType(方法名, 對象名)]給類對象zhangsan動態添加了對象方法run(),同理,Obj的另外一個類對象lisi不能調用這個方法
注:經過對象名添加的對象方法,只有這個對象能使用
"""
# 添加靜態方法
Obj.static_func = static_func
Obj.static_func()
obj.static_func()
obj2.static_func()
""" 由以上代碼可知,經過[類名.靜態方法名]給類Obj動態添加了靜態方法static_func(),Obj類的Obj對象和obj2對象都能調用這個方法 注:經過類名添加的靜態方法,這個類及這個類的全部對象都能使用 """ # 添加類方法 Obj.class_func = class_func Obj.class_func() obj.class_func()
obj2.class_func()
""" 由以上代碼可知,經過[類名.類方法名]給類Obj動態添加了類方法class_func(),Obj類的obj對象和obj2對象都能調用這個方法 注:經過類名添加的類方法,這個類及這個類的全部對象都能使用 """

4、__slots__的使用

  經過以上內容,咱們知道了如何動態的添加屬性和方法。可是,若是咱們想要限制class的屬性該怎麼辦?例如:只容許Obj實例添加name和age屬性。爲了達到這個目的,Python容許在定義class的時候,定義一個特殊變量__slots__來限制該class能添加的屬性。spa

class Obj(object):
    __slots__ = ('name', 'age')

obj = Obj() obj.name
= 'zhangyafei' obj.age = 23 obj.score = 99 # AttributeError: 'Obj' object has no attribute 'score' Obj.score = 100 print(obj.score) # 100 obj.score = 99 # AttributeError: 'Obj' object attribute 'score' is read-only

經過以上代碼可知,__slots__對Obj類的動態添加沒有限制,而Obj類對象obj不能再動態添加對象屬性和方法。code

對於__slot__有如下幾個須要注意的地方:對象

  • __slots__只對類對象進行限制,不對類進行限制
  • __slots__不只限制類對象的屬性,還限制類對象的方法
  • __slots__僅對當前類起做用,對繼承的子類不起做用
  • 在子類中定義__slots__,子類容許定義的屬性就是自身的__slots__加上父類的__slots__
相關文章
相關標籤/搜索