Python get child class inside parent class static/class 方法

Python get child class inside parent class static/class method

输出:

class Dog():
    def get_class():
        return __class__

class Cat():
    def get_class():
        return __class__

print(Dog.get_class())
print(Cat.get_class())

是:

<class '__main__.Dog'>
<class '__main__.Cat'>

我想用一个子类来干燥我的代码。但是输出:

class BaseClass():
    def get_class():
        return __class__

class Dog(BaseClass):
    pass

class Cat(BaseClass):
    pass

print(Dog.get_class())
print(Cat.get_class())

<class '__main__.BaseClass'>
<class '__main__.BaseClass'>

如何更改第二种情况的代码以获得与第一种情况相同的输出?

你快到了:

class BaseClass:
    @classmethod
    def get_class(cls):
        return cls

class Dog(BaseClass):
    pass


class Cat(BaseClass):
    pass

print(Dog.get_class())
print(Cat.get_class())

<class '__main__.Dog'>
<class '__main__.Cat'>

这里有几个不同的问题。

  1. 我们正在实施的逻辑只是“获取 class”。如果您想专门从 class 开始执行此操作,那么没有什么可做的,也没有理由在 BaseClassDogCat 得到那个结果 - 因为你 已经有了它 .
class BaseClass:
    pass

class Dog(BaseClass):
    pass

class Cat(BaseClass):
    pass

print(Dog)
print(Cat)
  1. __class__的特殊局部变量。它在定义方法的地方命名 class ,无论该方法是如何查找的,或者即使它被用作普通函数:
>>> class x:
...   def example(self):
...     print(__class__)
... 
>>> class y(x): pass
... 
>>> x().example()
<class '__main__.x'>
>>> y().example()
<class '__main__.x'>
>>> x.example(42)
<class '__main__.x'>
  1. 通常,不希望接收 class 实例的方法应该用 @classmethod@staticmethod 修饰.这样,代码仍然可以与 class 或实例一起使用。

规则是: @classmethod - 用 class 调用,第一个参数是 class 本身;用实例调用,第一个参数是实例的 class。参数应该在开始时包括一个以接收该参数。按照惯例,我们称该参数为 cls.

@staticmethod - 使用 class 或实例调用,不为调用添加任何参数。参数应仅列出将显式传递的内容。

无装饰器 - 使用 class 调用,不添加任何参数;用一个实例调用,该实例被添加。 这应该只用于实例,因此应该有一个参数来接收实例参数。按照惯例,我们称该参数为 self.

尝试在没有装饰器或 self 的 class 中使用函数违反了标准预期。它试图将 class 视为简单的命名空间。这不是它们的目的,甚至认为它有点的作用。


假设我们希望代码与 class(返回 class)或实例(返回实例的 class)一起工作,代码是微不足道的:一个 @classmethod 修饰的方法已经接收到一个参数,这正是我们想要的,在任何情况下,所以我们简单地 return 那个。因此:

class BaseClass:
    @classmethod
    def get_class(cls):
        return cls

class Dog(BaseClass):
    pass

class Cat(BaseClass):
    pass

print(Dog.get_class())
print(Dog().get_class())
print(Cat.get_class())
print(Cat().get_class())