Python3静态成员

2024-05-14 00:09:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在努力实现以下目标:

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

不知道如何实现。我肯定我遗漏了一些“self”前缀,但这是我第一次使用python和静态成员。

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

问题是函数的“username=get_username()”行尚未定义。如果我把用户名放在函数后面,那么它不是


Tags: 函数selfnone目标getreturnifis
2条回答

如果您不想失去引用A.username的能力,可以将类属性与一点元类一起使用:

class A(type):
    def __new__(cls, name, bases, attrs):
        # this allows B().username to also work
        attrs['username'] = property(lambda s: s.__class__.username)
        return type.__new__(cls, name, bases, attrs)
    @property
    def username(self):
        if not hasattr(self, '_username'):
            self._username = 'bar'
        return self._username

class B(object):
    __metaclass__ = A

print B.username
print B().username

首先,如果您要在之后立即重新分配Noneusername则没有理由分配None

其次,如果希望方法是静态方法,就不能给它一个self参数。如果你想要一个真正的静态方法,你必须显式地声明它。

    @staticmethod
    def get_username():
        if username is None:
        ...

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

在Python3中,任何常规方法在类上调用时都像静态方法一样工作,在实例上调用时像实例方法一样。因此,如果您确定永远不会想对实例调用a.get_username(),那么可以跳过decorator。但仍然需要去掉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

另一方面,username不一定是类成员。您可以通过向函数中添加成员、传递可变的默认变量或以各种其他方式记住,这些方式不需要感染类,并且允许您将get_username保留为静态方法而不是类方法。

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

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

同样,如果您确定没有人会尝试创建A的实例并在其上调用get_username,则可以删除@staticmethod

相关问题 更多 >