python 从实例调用类方法作为方法是不好的形式吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/692040/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 20:39:31  来源:igfitidea点击:

Is it bad form to call a classmethod as a method from an instance?

pythonclass-method

提问by Josh Gibson

Ex.

前任。

If I have something like this:

如果我有这样的事情:

class C(object):
    @classmethod
    def f(cls, x):
       return x + x

This will work:

这将起作用:

c = C()

c.f(2)
4

But is that bad form? Should I only call

但那是坏形式吗?我应该只打电话

C.f()

or

或者

c.__class__.f()

Obviously, this would only make sense in cases where f doesn't interact with self/cls expecting it to be class.

显然,这仅在 f 不与 self/cls 交互并期望它是类的情况下才有意义。

?

?

采纳答案by Toni Ru?a

If you are tempted to call a class method from an instance you probably don't need a class method.

如果您想从实例调用类方法,您可能不需要类方法。

In the example you gave a static method would be more appropriate precisely because of your last remark (no self/cls interaction).

在示例中,由于您的最后一句话(没有 self/cls 交互),您给出的静态方法会更合适。

class C(object):
    @staticmethod
    def f(x):
       return x + x

this way it's "good form" to do both

这样两者都是“好形式”

c = C()
c.f(2)

and

C.f(2)

回答by Matt Good

I don't recall using a classmethod like this from outside the class, but it is certainly ok for an instance method to call a classmethod on itself (e.g. self.foo()where foois a classmethod). This makes sure that inheritance acts as expected, and will call .foo()in the right subclass instead of the base class.

我不记得在类外部使用过这样的类方法,但是实例方法在自身上调用类方法当然是可以的(例如self.foo(),类方法在哪里foo)。这确保继承按预期运行,并将调用.foo()正确的子类而不是基类。

回答by Trey Stout

It's mainly just confusing looking. If I were using your class and saw this, it would make me wonder what other surprises are in there, it just looks like bad design.

它主要只是令人困惑的外观。如果我正在使用您的课程并看到这个,我会想知道那里还有什么其他惊喜,它看起来像糟糕的设计。

Is there a reason it's not just a staticmethod?

有没有理由它不仅仅是一个静态方法?

回答by vezult

C.f()is clearer than c_instance.f(), and c_instance.__class__.f()is just ugly. Since clarity and beauty are dearly loved characteristics in the python community, I'd tend to say that C.f() is the best route.

C.f()比 更清晰c_instance.f()c_instance.__class__.f()只是丑陋。由于清晰和美观是 Python 社区非常喜爱的特性,我倾向于说 Cf() 是最好的方法。

Is there any particular reason you even want to call it in either of the other ways?

你有什么特别的理由想用其他任何一种方式来称呼它吗?

回答by John Ellinwood

If you have an instance of C already, why do you need f() to be a class method? Not only is it bad form, its usually not necessary. Someone on the net says: "This is bad because it creates the impression that some instance variables in the object are used, but this isn't the case."

如果您已经有 C 的实例,为什么需要 f() 作为类方法?它不仅形式不好,而且通常没有必要。网上有人说:“这很糟糕,因为它给人的印象是使用了对象中的某些实例变量,但事实并非如此。”

Although, page 484 of learning pythonnotes that you can call the method either way and it will be exactly the same as long as you pass the same instance in.

虽然,学习 python 的第 484 页指出您可以以任何一种方式调用该方法,只要您传入相同的实例,它就会完全相同。

回答by David Culbreth

I came across this where I was calling some classmethods (that need to be classmethods so that I still have reference to the class) from a non-classmethod, like the following.

我遇到了这个,我从非类方法中调用了一些类方法(需要是类方法,以便我仍然可以引用该类),如下所示。

class A:
  def a(self, number):
    print("a", self, number)
    self.b(number)

  @classmethod
  def b(cls, number):
    print("b", cls, number + 1)
    cls.c(number)

  @classmethod
  def c(cls, number):
    print("c", cls, number * 2)



b = A()
b.a(3) 

The above code produces the following result:

上面的代码产生以下结果:

a <__main__.A object at 0x000001FAC09FE358> 3
b <class '__main__.A'> 4
c <class '__main__.A'> 6

I'm not saying that it's the best convention, but it doesn't break anything in Python 3.6

我并不是说这是最好的约定,但它不会破坏 Python 3.6 中的任何内容