Python 3静态成员

s5s*_*s5s 7 python python-3.x

我想要实现以下目标:

class A:
    username = None
    username = get_username()
    def get_username(self):
        if username is None:
            try:
                uname = os.environ["USER"]
            except:
                printf("Couldn't find a user name")
            return uname
        return username
Run Code Online (Sandbox Code Playgroud)

不知道如何实现这一目标.我确定我错过了一些"自我".前缀,但这是我第一次使用python和静态成员.

从某种意义上说,我想要一个具有一些成员和函数的类来计算这些成员的值,但我不想重新计算.我也希望这些是静态函数和数据成员.

问题是该行"username = get_username()"尚未定义该函数.如果我在功能之后输入用户名,那么它就不是

aba*_*ert 11

首先,没有理由分配Noneusername你,如果你刚刚重新分配它.

其次,如果您希望该方法是静态方法,则不能给它一个self参数.如果你想要一个真正的静态方法,你必须明确声明它.

    @staticmethod
    def get_username():
        if username is None:
        ...
Run Code Online (Sandbox Code Playgroud)

否则,你需要一个类(的实例self)来调用它,而你还没有.

在Python 3中,任何常规方法在类上调用时都像静态方法,就像在实例上调用时的实例方法一样.所以,如果你确定你永远不想要调用a.get_username()实例a,你可以跳过装饰器.但你仍然需要摆脱self参数.

我认为你实际上要做的是使用类变量来记忆静态方法的结果.你不能这样做,但你可以使用类变量来记忆方法的结果,这可能足够接近.这看起来像这样:

class A:
    username = None
    @classmethod
    def get_username(cls):
        if cls.username is None:
            try:
                uname = os.environ["USER"]
            except:
                print("Couldn't find a user name")
            else:
                cls.username = uname
        return cls.username
Run Code Online (Sandbox Code Playgroud)

另一方面,没有充分的理由用户名必须是类成员.您可以通过向函数添加成员,通过传递可变的默认变量,或者以不需要感染类的其他各种方式,以及允许您get_username作为静态方法而不是类方法离开来进行memoize .

但实际上,最好的解决方案是在PyPI上找到一个memoization库,在ActiveState的配方列表中等等,这样你就可以这样写:

class A:
    @memoize
    @staticmethod
    def get_username():
        try:
            return os.environ["USER"]
        except:
            print("Couldn't find a user name")
            return None
Run Code Online (Sandbox Code Playgroud)

同样,你可以放弃,@staticmethod如果你确定没有人会尝试创建一个实例A并调用get_username它.