「Python系列」 Python 之面向對象(三)


「Python系列」 Python 之面向對象(三)

實例方法

現在,我們創建兩個實例方法:

  • .set_z(): 修改_z的值
  • .get_z(): 獲取_z的值

請記住,每個實例方法的第一個參數(按慣例稱為self)是指對象本身,但是在調用該方法時我們不提供它:

<code>>>> class MyClass:
... def __init__(self, arg_1, arg_2, arg_3):
... self.x, self._y, self.__z = arg_1, arg_2, arg_3
...
... def set_z(self, value):
... self.__z = value
...
... def get_z(self):
... return self.__z
...
>>> b = MyClass(2, 4, 8)/<code>

.get_z()和.set_z()方法提供了一個常規接口來檢索和修改.__ z的值:

<code>>>> b.get_z()
8
>>> b.set_z(16)
>>> vars(b)
{'x': 2, '_y': 4, '_MyClass__z': 16}/<code>

.get_z()和.set_z()可以帶來其他功能,例如檢查數據的有效性。此類方法啟用封裝,這是面向對象編程中的主要概念之一。

屬性

訪問和修改數據屬性的另一種方法(也許是更Python化的方法)是使用properties。它們封裝了方法(getter,setter和Deleters),但其行為類似於普通的數據屬性。

這是屬性.z的實現,該屬性具有與.get_z()和.set_z()相同的功能:

<code>>>> class MyClass:
... def __init__(self, arg_1, arg_2, arg_3):
... self.x, self._y, self.__z = arg_1, arg_2, arg_3
...
... @property
... def z(self):
... return self.__z
...
... @z.setter
... def z(self, value):
... self.__z = value
...
>>> b = MyClass(2, 4, 8)/<code>

這是我們可以使用相應的屬性.z訪問和修改數據屬性.__ z的方法​​:

<code>>>> b.z
8
>>> b.z = 16
>>> vars(b)
{'x': 2, '_y': 4, '_MyClass__z': 16}/<code>

該代碼比前面的示例更短,並且可以說更優雅。

類和靜態方法

除了實例方法和屬性之外,類還可以具有

類方法靜態方法

讓我們向MyClass添加三個方法:

<code>>>> class MyClass:
... def __init__(self, arg_1, arg_2, arg_3):
... self.x, self._y, self.__z = arg_1, arg_2, arg_3
...
... def f(self, arg):
... print('instance method f called')
... print(f'instance: {self}')
... print(f'instance attributes:\\n{vars(self)}')
... print(f'class: {type(self)}')
... print(f'arg: {arg}')
...
... @classmethod
... def g(cls, arg):
... print('class method g called')
... print(f'cls: {cls}')
... print(f'arg: {arg}')
...
... @staticmethod
... def h(arg):
... print('static method h called')
... print(f'arg: {arg}')
...
>>> c = MyClass(2, 4, 8)/<code>

.f()方法是一個實例方法。實例方法必須具有引用對象本身的第一個參數。他們可以訪問帶有self的對象,帶有vars(self)或self .__ dict__的對象的數據屬性,與具有type(self)或self .__ class__的對象相對應的類以及它們自己的參數。

.g()方法用@classmethod裝飾。這使其成為一個類方法。每個類方法必須具有引用該類的第一個參數,按慣例稱為cls。與實例方法一樣,我們沒有明確提供與cls相對應的參數。類方法可以使用cls和自己的參數訪問該類。

.h()方法用@staticmethod裝飾。這使其成為靜態方法。靜態方法只能訪問自己的參數。

這是通常在Python中調用實例方法的方式:

<code>>>> c.f('my-argument')
instance method f called
instance: <__main__.myclass object="" at="">
instance attributes:
{'x': 2, '_y': 4, '_MyClass__z': 8}
class: <class>
arg: my-argument/<class>/<code>

通常使用類而不是實例直接調用類方法和靜態方法:

<code>>>> MyClass.g('my-argument')
class method g called
cls: <class>
arg: my-argument
>>> MyClass.h('my-argument')
static method h called
arg: my-argument/<class>/<code>

請記住,我們沒有傳遞與類方法的第一個參數cls相對應的參數。

但是,類方法和靜態方法可以這樣調用:

<code>>>> c.g('my-argument')
class method g called
cls: <class>
arg: my-argument
>>> c.h('my-argument')
static method h called
arg: my-argument/<class>/<code>

當我們調用cg或ch並且沒有這樣的名稱的實例成員時,Python將搜索一個類和靜態成員。


分享到:


相關文章: