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

[Python]Can we call an user-defined instance method inside a @classmethod function?

一个新手问的问题是,我试着用decorator@classmethod在方法内部调用一个方法,你知道如何实现这一点吗?例如,我有:

1
2
3
4
5
6
7
8
9
10
class A():
    def B(self):
    #do something
    return something

    @classmethod
    def C(cls):
    #do something
    x = B() #call B method
    return None

我有个错误:

1
NameError: global name 'B' is not defined

我可以调用B吗?或者我也可以将B定义为类方法吗?


这里的问题不是您的函数是"用户定义的",而是"x=b()"不调用类中名为"b"的方法,而是调用全局命名空间中名为"b"的方法。

要说明发生了什么,请查看以下代码:

1
2
3
4
5
6
7
8
9
10
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()应该是一个实例方法本身。

类方法和实例方法之间的区别说明了类方法和实例方法之间的区别。


要使其工作,您需要这样做:

1
2
3
4
5
6
7
8
9
10
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


类方法是不需要实例数据的方法。如果B需要使用self所隐含的实例数据,那么A不应该是类方法。如果B不需要实例数据,可以将其定义为类方法,并使用cls.b()调用它。