来自新手的一个问题,我尝试用装饰器@classmethod调用方法里面的一个方法,任何想法如何实现呢?例如,我有:
class A():
def B(self):
#do something
return something
@classmethod
def C(cls):
#do something
x = B() #call B method
return None
我收到了错误:
NameError: global name 'B' is not defined
我可以调用B还是将B定义为类方法?
答案 0 :(得分:1)
这里的问题不是你的功能是"用户定义",问题是" x = B()"没有调用一个名为" B"在你的类中,它调用一个名为" B"的方法。在全局命名空间中。
要说明发生了什么,请查看以下代码:
B="1"
class A():
B="2"
def myfunc(cls):
print B
a = A()
a.myfunc()
如果你跑了,你会看到输出是1
。
如果您将print
语句更改为print A.B
,您将获得2
。
在您的情况下,您需要致电A.B()
,而不仅仅是B()
但是,正如其他人所指出的那样,B()
是一种实例方法。它期望它传递的第一个参数是该类的实例。根据B的作用,您可能会因为没有实例传递而导致问题。您可以通过传递一些其他对象(例如类本身)或通过创建要传入的新对象以各种方式解决此问题;但对我来说,如果C()需要调用实例方法,C()应该是一个实例方法本身。
Difference between Class and Instance methods讨论了类和实例方法之间的区别。
答案 1 :(得分:0)
类方法是不需要实例数据的方法。如果B需要使用self
暗示的实例数据,那么A不应该是类方法。如果B不需要实例数据,您可以将其定义为类方法并使用cls.B()调用它。
答案 2 :(得分:0)
要做到这一点,你需要做这样的事情:
class A():
def B(self):
#do something (with self! so this requires A to be instantiated!)
return something
@classmethod
def C(cls):
#do something
return cls().B() #instantiate class, call B method, and return results