[Python]我们可以在@classmethod函数中调用用户定义的实例方法吗?

时间:2014-07-11 22:18:42

标签: python instance-methods class-method instance-method

来自新手的一个问题,我尝试用装饰器@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定义为类方法?

3 个答案:

答案 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