龙空技术网

七个Python问题,来扫扫盲

新梦想IT教育 71

前言:

眼前我们对“python问题解答”都比较重视,我们都想要知道一些“python问题解答”的相关知识。那么小编同时在网络上网罗了一些关于“python问题解答””的相关资讯,希望你们能喜欢,同学们快快来了解一下吧!

 你可能知道 Python 里面的魔法函数,比如 __add__ 和 __sub__ 代表 + - 运算符,表示 obj +/- something,但你可能不知道还有一个 __radd__,__rsub__ 函数,可以表示 something +/- obj。

  这 7 个问题,我是有收获的,整理如下:

  1、反射算术运算符

  你可能知道 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__

  2、__getattr__ vs __getattribute__

  __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

  3、super().__init__() 的另一种写法

  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 参数。

  4、检查子类的方法

  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__() 只能检查直接子类。

  5、多重集成时,同名函数,子类用的是哪一个?

  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 方法被集成。

  多充继承让人困惑,不用为好。

  6 __invert__ 魔法函数

  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)

  7、不使用 class 来创建类

  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问题解答