這7 個問題,我是有收穫的,整理如下:
你可能知道Python 裡面的魔法函數,例如 __add__ 和 __sub__代表- 運算符,表示obj /- something,但你可能不知道還有一個 __radd__,__rsub__ 函數,可以表示something /- obj。
舉例如下:
class Dog: def __add__(self, other): return "from __add__" def __radd__(self, other): return "from __radd__" dog = Dog() print(dog + 1) # from __add__ print(1 + dog) # from __radd__
__getattr__ 魔術方法只有在我們試圖獲取不存在的屬性時才被調用,__getattribute__ 在每次我們嘗試存取屬性時都會被呼叫。
程式碼如下:
class Dog: def __init__(self, name, age): self.name = name self.age = age def __getattr__(self, key): return f"{key} not found" dog = Dog("taidi", 5) print(dog.name)# taidi print(dog.age) # 5 print(dog.breed) # breed not found
class Dog: def __init__(self, name, age): self.name = name self.age = age def __getattribute__(self, key): return f"{key} not found" dog = Dog("taidi", 5) print(dog.name)# name not found print(dog.age) # age not found print(dog.breed) # breed not found
class Animal: def __init__(self, name, age): self.name = name self.age = age class Dog(Animal): def __init__(self, name, age, breed): super().__init__(name, age) self.breed = breed
等價於:
class Animal: def __init__(self, name, age): self.name = name self.age = age class Dog(Animal): def __init__(self, name, age, breed): Animal.__init__(self, name, age) self.breed = breed
請注意,Animal.__init__(self, name, age) 不能少了self 參數。
class Animal: pass class Dog(Animal): pass class Cat(Animal): pass class GermanSheperd(Dog): pass print(Animal.__subclasses__()) # [<class '__main__.Dog'>, <class '__main__.Cat'>]
不過,.__subclasses__() 只能檢查直接子類別。
class A: def test(self): print("A") class B: def test(self): print("B") class C(A, B): pass C().test() # A
A 和 B 都有 test 方法,那麼 C 到底整合了哪一個呢?在 Python 中,最左邊的類別優先。
在這裡,A 是最左邊的父類,因此 A 的 test 方法被整合。
多充繼承讓人困惑,不用為好。
class Dog: def __invert__(self): return "test" dog = Dog() print(~dog) # test
~ 運算子代表“位元非”,通常用於反轉內容。一個更有意義的例子如下:
class Coordinate: def __init__(self, x, y): self.x = x self.y = y def __str__(self): return f"({self.x}, {self.y})" def __invert__(self): return Coordinate(-self.x, -self.y) a = Coordinate(3, 4) b = ~a print(a, b) # (3, 4) (-3, -4)
def init(self, name, age): self.name = name self.age = age def bark(self): print("woof") Dog = type("Dog", (), {"__init__":init, "bark":bark}) dog = Dog("taidi", 10) print(dog.name) print(dog.age) # taidi # 10
在這裡,我們將 3 個參數傳遞給 type 以建立我們的類別。
第一個參數 __name__ 是類別的名稱 第二個參數 __bases__ 是一個包含父類別的元組 第三個參數 __dict__ 是包含屬性與方法的字典。
等價於:
class Dog: def __init__(self, name, age): self.name = name self.age = age def bark(self): print("woof")
以上是七 個 Python 問題,來掃盲的詳細內容。更多資訊請關注PHP中文網其他相關文章!