代码之家  ›  专栏  ›  技术社区  ›  Bradley Marques

Python在父类静态/类方法中获取子类

  •  1
  • Bradley Marques  · 技术社区  · 2 年前

    输出:

    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'>
    

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

    2 回复  |  直到 2 年前
        1
  •  1
  •   baskettaz    2 年前

    您就快到了:

    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'>
    
        2
  •  1
  •   Karl Knechtel    2 年前

    这里有几个不同的问题。

    1. 我们实现的逻辑只是“获取类”。如果您想从特定且仅限于 来自班级 ,则无需执行任何操作,也没有理由在 BaseClass Dog Cat 为了得到这个结果-因为你 已经有了 .
    class BaseClass:
        pass
    
    class Dog(BaseClass):
        pass
    
    class Cat(BaseClass):
        pass
    
    print(Dog)
    print(Cat)
    
    1. __class__ 是一个特殊的局部变量 is used for the implementation of super() . 它为类命名 定义方法的位置 ,无论该方法是如何查找的,也不管它是否用作普通函数:
    >>> 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. 正常地 ,不希望接收类实例的方法应修饰为 @classmethod @staticmethod . 这样,代码仍然可以用于类或实例。

    规则如下: @classmethod类方法 -使用类调用时,第一个参数是该类本身;使用实例调用时,第一个参数是实例的类。参数应在开始处包含一个参数以接收该参数。按照惯例,我们称之为参数 cls .

    @静态法 -使用类或实例调用时,不会为调用添加参数。参数应仅列出将显式传递的内容。

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

    尝试在没有修饰符或 自己 违反标准预期。它试图将该类视为一个简单的命名空间。这是 不是为了什么 ,甚至认为 某种程度上 作品


    假设我们希望代码与一个类(返回该类)或一个实例(返回该实例的类)一起工作,那么代码很简单:a @classmethod类方法 -修饰的方法已经接收到一个参数,在任何情况下,它都是我们想要的,所以我们只需返回它。因此:

    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())