【问题标题】:Writing a python method that refers to both the instance and the class编写一个引用实例和类的python方法
【发布时间】:2017-04-13 21:13:13
【问题描述】:

假设我们在 Python 中有一个 Pet 类:

class Pet(object):
    num_pets = 0

    def __init__(self, name):
        self.name = name
        Pet.num_pets += 1

    def speak(self):
        print("My name's %s and the number of pets is %d" % (self.name, self.num_pets))

我希望 init 方法创建一个实例,同时更新类的属性。有没有比上面的代码更优雅的方法来做到这一点?我尝试将 selfcls 传递给 init 方法,然后在 num_pets 递增的地方引用 cls 而不是 Pet ,但这不起作用。

【问题讨论】:

  • 我看到上面的代码已经足够优雅了。除非num_pets 是按类管理的属性。我看不出有什么明显的理由考虑在这里使用类方法的需要。

标签: python oop class-method


【解决方案1】:

您可以使用classmethod 来增加宠物的数量:

class Pet(object):
    num_pets = 0

    def __init__(self, name):
        self.name = name
        self.incr_num_pets()

    @classmethod
    def incr_num_pets(cls):
        cls.num_pets += 1

或者,您可以在 type(self) 上增加 num_pets

def __init__(self, name):
    self.name = name
    type(self).num_pets += 1

虽然我发现第二种方法稍微不那么优雅,即使它输入的次数更少。

【讨论】:

    【解决方案2】:

    在您的情况下,您可以将__new____init__ 一起使用:

    class Pet(object):
        num_pets = 0
    
        def __new__(cls, *args, **kwargs):
            cls.num_pets += 1
            return object.__new__(cls)
    
        def __init__(self, name):
            self.name = name
    

    【讨论】:

      【解决方案3】:

      您可以使用self.__class__ 访问自己的类,这意味着您的__init__ 可以如下所示:

      def __init__(self, name):
          self.name = name
          self.__class__.num_pets += 1
      

      【讨论】:

      • 不错的一个!谢谢!
      猜你喜欢
      • 2015-06-10
      • 1970-01-01
      • 1970-01-01
      • 2017-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-13
      相关资源
      最近更新 更多