从实例调用类方法作为方法是一种不好的形式吗?
前任。
如果我有这样的东西:
class C(object):
@classmethod
def f(cls, x):
return x + x
这会起作用:
c = C()
c.f(2)
4
但这是不好的形式吗? 我应该只调用
C.f()
or
c.__class__.f()
显然,这只有在 f 不与 self/cls 交互并期望它是类的情况下才有意义。
?
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.
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
如果您想从实例调用类方法,您可能不需要类方法。
在示例中,由于您最后的评论(没有 self/cls 交互),您给出的静态方法将更合适。
是“良好的形式”
这样,两者兼而有之
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).
this way it's "good form" to do both
and
我不记得在类外部使用过这样的类方法,但是实例方法本身调用类方法当然是可以的(例如
self.foo()
wherefoo< /code> 是一个类方法)。 这可以确保继承按预期运行,并将在正确的子类而不是基类中调用
.foo()
。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()
wherefoo
is a classmethod). This makes sure that inheritance acts as expected, and will call.foo()
in the right subclass instead of the base class.主要是看起来很混乱。 如果我在使用你的课程并看到这个,它会让我想知道里面还有什么其他惊喜,它看起来像是糟糕的设计。
它不仅仅是静态方法有什么原因吗?
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?
Cf()
比c_instance.f()
更清晰,而c_instance.__class__.f()
则很丑陋。 由于清晰和美观是 python 社区深受喜爱的特性,因此我倾向于说 Cf() 是最好的路线。您是否有任何特殊原因想要以其他方式调用它?
C.f()
is clearer thanc_instance.f()
, andc_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.Is there any particular reason you even want to call it in either of the other ways?
我在从非类方法调用一些类方法(需要是类方法,以便我仍然可以引用该类)时遇到了这个问题,如下所示。
上面的代码产生以下结果:
我并不是说这是最好的约定,但它不会破坏 Python 3.6 中的任何内容
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.
The above code produces the following result:
I'm not saying that it's the best convention, but it doesn't break anything in Python 3.6
如果您已经有一个 C 实例,为什么需要 f() 作为类方法? 这不仅是不好的形式,而且通常没有必要。 网上有人说:“这很糟糕,因为它给人的印象是对象中的某些实例变量被使用了,但事实并非如此。”
不过,学习的第 484 页python 指出,您可以以任何一种方式调用该方法,只要传入相同的实例,它就会完全相同。
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."
Although, page 484 of learning python notes that you can call the method either way and it will be exactly the same as long as you pass the same instance in.
我认为问题在于风格,也就是说,如果你想要一个类方法,你应该将其称为类方法
MyClass.my_func()
,还是作为实例方法myinst.my_func()。 记录对
@classmethod<的解释/code> 装饰器的优点是它允许您像调用实例方法一样调用类方法。 我在下面提供了一个示例来说明这一点。
至于风格,我认为无论如何都不应该让人们感到困惑,它实际上是方法实现细节。 如果您在实例的上下文中调用类方法(即作为类实例对象的用户,或在类实例方法内部),那么将类方法作为另一个实例方法调用是完全可以的,甚至可能更愿意不这样做突出显示有关被调用方法的一些实现细节。
我该怎么办? 如果我将实例属性传递给类方法,我可能会在 MyClass.my_func(self.some_value) 中调用类方法,而不是调用 self.my_func(self.some_value) 因为看到后者让我想知道为什么
my_func
不读取self.some_value
本身,而不是让我传递它。 否则我真的不介意任何一种形式。当然,类是用来实例化的,最大的错误是程序员将它们用作无状态方法的某种命名空间。
回报
I think the question is that of style, which is to say, if you want a class method, should you call it as a class method
MyClass.my_func()
, or as an instance methodmyinst.my_func()
. On of the of documented explinations of the@classmethod
decorator is that it will allow you to call the class method as if it was an instance method. I have included an example showing this below.As for style, I think it should not be confusing to people either way, it really is the method implementation detail. If you are calling the class method in the context of an instance (i.e. as a user of a class instance object , or inside class instance methods), then calling class method as just another instance method is perfectly okay, and maybe even preferred to not highlighting some implementation detail about the method being called.
What would I do? If I was passing an instance attribute into a classmethod, I'd probably call the classmethod in the
MyClass.my_func(self.some_value)
, rather then callingself.my_func(self.some_value)
because seeing the latter makes me wonder whymy_func
isn't readingself.some_value
itself, instead of making me pass it along. Otherwise I really don't mind either form.Of course, classes are meant to be instantiated, and the biggest faux pas is programmers using them as some sort of namespace for stateless methods.
returns