Python中静态方法如何访问类变量?

74

这是我的代码长这个样子

class InviteManager():
    ALREADY_INVITED_MESSAGE = "You are already on our invite list"
    INVITE_MESSAGE = "Thank you! we will be in touch soon"

    @staticmethod
    @missing_input_not_allowed
    def invite(email):
        try:
            db.session.add(Invite(email))
            db.session.commit()
        except IntegrityError:
            return ALREADY_INVITED_MESSAGE
        return INVITE_MESSAGE

当我运行我的测试时,我看到

NameError: global name 'INVITE_MESSAGE' is not defined

如何在@staticmethod内部访问INVITE_MESSAGE

6个回答

69

你可以通过InviteManager.INVITE_MESSAGE访问它,但更好的解决方案是将静态方法改为类方法:

@classmethod
@missing_input_not_allowed
def invite(cls, email):
    return cls.INVITE_MESSAGE

(或者,如果您的代码真的就像看起来那样简单,您可以用模块中的一堆函数和常量替换整个类。模块是命名空间。)


1
或者将其作为模块级函数。 - user395760
1
@delnan:是的。有时候你需要一个类或静态方法,尤其是涉及继承或鸭子类型的情况下。 - Fred Foo
1
Python为什么允许通过staticmethod访问class variable?是否有必要使用classmethod?如果它们都可以访问类变量,那么classmethodstaticmethod之间的不同用例是什么? - JavaSa
类方法可以获取对子类的引用,因此它们可以在基类中编写,但在不同的子类中会有不同的行为,因为它们的行为可能取决于类。此外,静态方法不会获取对类的引用,因此如果您需要引用类,则使用cls更加干净,例如当类的名称更改时不会导致代码出错。 - antont

13

尝试:

class InviteManager():
    ALREADY_INVITED_MESSAGE = "You are already on our invite list"
    INVITE_MESSAGE = "Thank you! we will be in touch soon"

    @staticmethod
    @missing_input_not_allowed
    def invite(email):
        try:
            db.session.add(Invite(email))
            db.session.commit()
        except IntegrityError:
            return InviteManager.ALREADY_INVITED_MESSAGE
        return InviteManager.INVITE_MESSAGE

InviteManager 是在其静态方法的范围内。


5
这比所有这些都简单得多:
只需将__class__添加到类变量中即可,如下所示:
return __class__.ALREADY_INVITED_MESSAGE
        return __class__.INVITE_MESSAGE

没有必要提及类名(InviteManager),也不需要使用 classmethod


更多信息:__class__ cell 是在PEP 3135中引入的。 - eugenhu

5

我刚刚意识到,我需要使用 @classmethod

class InviteManager():
    ALREADY_INVITED_MESSAGE = "You are already on our invite list"
    INVITE_MESSAGE = "Thank you! we will be in touch soon"

    @classmethod
    @missing_input_not_allowed
    def invite(cls, email):
        try:
            db.session.add(Invite(email))
            db.session.commit()
        except IntegrityError:
            return cls.ALREADY_INVITED_MESSAGE
        return cls.INVITE_MESSAGE

您可以在这里了解相关内容,其中涉及到Python中静态方法和类方法的区别。

3

简单地理解类级别的变量/方法和实例级别的变量/方法。

在使用静态方法时,您不会使用self关键字,因为self关键字用于表示类的实例或使用类的实例变量。实际上,可以使用class_name,如下面的示例所示:

class Myclass():
    msg = "Hello World!"

    @staticmethod
    def printMsg():
        print(Myclass.msg)



Myclass.printMsg() #Hello World!
print(Myclass.msg) #Hello World!
Myclass.msg = "Hello Neeraj!"
Myclass.printMsg() #Hello Neeraj!
print(Myclass.msg) #Hello Neeraj!

2

您可以使用 InviteManager.INVITE_MESSAGEInviteManager.ALREADY_INVITED_MESSAGE 访问您的属性,而无需更改它们的声明。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接