python中方法的運作
方法是作為類的屬性(attribute)儲存的函式,你可以以下面的方式宣告和獲取函式:
class pizza(object):
… definit(self, size):
… self.size = size
… def get_size(self):
… return self.size
pizza.get_size
這又指什麼呢?很快我們就會知道,試著呼叫一下:
pizza.get_size()
traceback (most recent call last):
file 「」, line 1, in
typeerror: unbound method get_size() must be called with pizza instance as first argument (got nothing instead)
這裡我們不能呼叫這個方法是因為它沒有被繫結到任一 pizza 的例項上。乙個方法需要乙個例項作為它第乙個引數
pizza.get_size(pizza(42))42
現在可以了!我們試用乙個例項作為 get_size 方法的第乙個引數呼叫了它,所以一切變得很美好。
但是你很快會同意,這並不是乙個很漂亮的呼叫方法的方式;因為每次我們想呼叫這個方法都必須使用到類。並且,如果我們不知道物件是哪個類的例項,這種方式就不方便了。所以,python 為我們準備的是,它將類 pizza 的所有的方法繫結到此類的任何例項上。
這意味著類 pizza 的任意例項的屬性 get_size 是乙個已繫結的方法:第乙個引數是例項本身的方法。
pizza(42).get_size
>
pizza(42).get_size()
如我們預期,現在不需要提供任何引數給 get_size,因為它已經被繫結(bound),它的 self 引數是自動地設為 pizza 類的例項。
下面是乙個更好的證明:
m = pizza(42).get_size
m
>
m()42
因此,你甚至不要儲存乙個對 pizza 物件的飲用。它的方法已經被繫結在物件上,所以這個方法已經足夠。
但是如何知道已繫結的方法被繫結在哪個物件上?技巧如下:
m = pizza(42).get_size
m.self
<main.pizza object at 0x10314b390>
m == m.self.get_size
true
易見,我們仍然儲存著乙個對物件的引用,當需要知道時也可以找到。
在 python3 中,歸屬於乙個類的函式不再被看成未繫結方法(unbound method),但是作為乙個簡單的函式,如果要求可以繫結在物件上。所以,在 python3 中原理是一樣的,模型被簡化了。
class pizza(object):
… definit(self, size):
… self.size = size
… def get_size(self):
… return self.size
pizza.get_size
靜態方法
靜態方法是一類特殊的方法。有時,我們需要寫屬於乙個類的方法,但是不需要用到物件本身。例如:
class pizza(object):
@staticmethod
def mix_ingredients(x, y):
return x + y
def cook(self):
return self.mix_ingredients(self.cheese, self.vegetables)
這裡,將方法 mix_ingredients 作為乙個非靜態的方法也可以 work,但是給它乙個 self 的引數將沒有任何作用。
這兒的 decorator@staticmethod 帶來一些特別的東西:
pizza().cook is pizza().cook
false
pizza().mix_ingredients is pizza().mix_ingredients
true
pizza().mix_ingredients is pizza.mix_ingredients
true
pizza()
<main.pizza object at 0x10314b410>
pizza()
<main.pizza object at 0x10314b510>
python 不需要對每個例項化的 pizza 物件例項化乙個繫結的方法。
繫結的方法同樣是物件,建立它們需要付出代價。這裡的靜態方法避免了這樣的情況:
降低了閱讀**的難度:看到 @staticmethod 便知道這個方法不依賴與物件本身的狀態;允許我們在子類中過載mix_ingredients方法。如果我們使用在模組最頂層定義的函式 mix_ingredients,乙個繼承自 pizza 的類若不過載 cook,可能不可以改變混合成份(mix_ingredients)的方式。
類方法
什麼是類方法?類方法是繫結在類而非物件上的方法!
class pizza(object):
… radius = 42
… @classmethod
… def get_radius(cls):
… return cls.radius
pizza.get_radius
>
pizza().get_radius
>
pizza.get_radius is pizza().get_radius
false
pizza.get_radius()
不管你如何使用這個方法,它總會被繫結在其歸屬的類上,同時它第乙個引數是類本身(記住:類同樣是物件)
何時使用這種方法?類方法一般用於下面兩種:
工廠方法,被用來建立乙個類的例項,完成一些預處理工作。如果我們使用乙個 @staticmethod 靜態方法,我們可能需要在函式中硬編碼 pizza 類的名稱,使得任何繼承自 pizza 類的類不能使用我們的工廠用作自己的目的。
class pizza(object):
definit(self, ingredients):
self.ingredients = ingredients
@classmethod
def from_fridge(cls, fridge):
return cls(fridge.get_cheese() + fridge.get_vegetables())
2. 靜態方法調靜態方法:如果你將乙個靜態方法分解為幾個靜態方法,你不需要硬編碼類名但可以使用類方法。使用這種方式來宣告我們的方法,pizza這個名字不需要直接被引用,並且繼承和方法過載將會完美運作。
class pizza(object):
definit(self, radius, height):
self.radius = radius
self.height = height
@staticmethod
def compute_circumference(radius):
return math.pi * (radius ** 2)
@classmethod
def compute_volume(cls, height, radius):
return height * cls.compute_circumference(radius)
def get_volume(self):
return self.compute_volume(self.height, self.radius)
類方法,靜態方法
coding utf 8 class test object walk 為普通方法只能被物件instance呼叫,play 為靜態方法可以被物件和classname呼叫,eat為類方法,可以被物件和classname呼叫。此外pep8中一種程式設計風格,self通常用作例項方法的第一引數,cls通常...
類方法 靜態方法
類方法 class goods discount 0.8 def init self,name,price self.name name self.price price property def price self return self.price goods.discount classme...
類方法,靜態方法
7.靜態方法與類方法 按引數區分 例項方法 定義 第乙個引數必須是例項物件,該引數名一般約定為 self 通過它來傳遞例項的屬性和方法 也可以傳類的屬性和方法 呼叫 只能由例項物件呼叫。靜態方法 定義 使用裝飾器 staticmethod。引數隨意,沒有 self 和 cls 引數,但是方法體中不能...