首先直接看代一組代碼:python
class test1(): def __init__(self, a): self.a = a def __call__(self, b): self.b = b print(self.b) return (self.a + self.b) n1 = test1(1) print(hasattr(n1, '__call__')) >>>True class test2(): def __init__(self, a): self.a = a n2 = test2(2) print(hasattr(n2, '__call__')) >>>False
上面代碼中定義了兩個類,分別是test1類和test2類,不一樣的是,test1類中多定義了一個__call__()
函數。分別實例化這兩個類,而後採用hasattr()
函數查看兩個實例對象,就能夠總結出如下__call__()
函數的做用:
__call__()
函數,或者在python中稱之爲方法
,其做用在於給類的實例提供可調用的接口,即除了類自己是個可調用對象以外,類的實例也是一個可調用對象。
上面說明書式的定義很差理解,以例子爲說明:dom
n1 = test1(1) value = n1(2) print(value) >>>3
上面代碼中n1
是類test1的一個實例化對象,有了__call__()
函數,就能夠像初始化類的實例那樣,寫出第二行那樣的代碼。更爲通俗的說,就是咱們實際想要寫的操做函數,均可以放到__call__()
函數的內部中進行,這樣就可讓類的實例做爲普通python函數那樣使用。實際上,就能夠理解成是一種()
運算符的重載。函數
g = lambda x:x+1 # (1) def g(x): # (2) return x+1
上面代碼(1)徹底等同於(2),代碼精簡,實際效率不會有改變學習
import numpy as np # np.random.randint(low, high, size) np.random.randint(1,3,size = [1,3]) >>>[[1],[2],[2]]
該函數產生[low, high)之間的隨機整數,格式爲指定size的shapecode
# 原始版本 class Celsius: def __init__(self, temperature = 0): self.temperature = temperature def to_fahrenheit(self): return (self.temperature * 1.8) + 32 # 普通添加限制版本 class Celsius: def __init__(self, temperature = 0): self.set_temperature(temperature) def to_fahrenheit(self): return (self.get_temperature() * 1.8) + 32 # new update def get_temperature(self): return self._temperature def set_temperature(self, value): if value < -273: raise ValueError("Temperature below -273 is not possible") self._temperature = value # property版本 class Celsius: def __init__(self, temperature = 0): self._temperature = temperature def to_fahrenheit(self): return (self.temperature * 1.8) + 32 @property def temperature(self): print("Getting value") return self._temperature @temperature.setter def temperature(self, value): if value < -273: raise ValueError("Temperature below -273 is not possible") print("Setting value") self._temperature = value
@property
的產生來源於現實須要,原始版本的Celsius在建立實例時,沒法給出溫度的限制區間。若是直接經過添加get()
函數和set()
函數的方法來設定限制,那麼在訪問實例的屬性的時候,代碼已經變成沒法向後兼容了。所以,爲了兼顧向後兼容性和設定限制,@property
應運而生。
實際上,觀察@property
的代碼,能夠發現溫度已經從公有屬性,變成私有屬性,也就是說,爲了向後兼容性,@property
提供了訪問私有屬性的接口。對象
Tips : An underscore (_) at the beginning is used to denote private variables in Python.
python中用前置下劃線表明私有變量接口