我可以在一个类中设置一个类变量吗?

时间:2020-10-12 18:31:35

标签: python

请考虑以下简单类:

class ExampleClass():

    def __init__(self, foo):
        self.foo = foo

    def calc_bar(self):
        baz = self.get_baz()
        return baz * self.foo

    @staticmethod
    def get_baz():
        return <result of unchanging database query>

然后我将其与以下内容一起使用:

from module1 import ExampleClass

foo = 10
myobj = ExampleClass(foo)
bar = myobj.calc_bar()

每次调用calc_bar方法时,都会查询数据库的当前构建方式。

我如何将get_baz方法的输出转换为只为该类设置一次的类属性?

我可以通过以下方式手动完成操作:

class ExampleClass():

    baz = None

    def __init__(self, foo):
        self.foo = foo

    def calc_bar(self):
        return self.baz * self.foo

---

from module1 import ExampleClass

ExampleClass.foo = <result of unchanging database query>
foo = 10
myobj = ExampleClass(foo)
bar = myobj.calc_bar()

有没有一种方法可以从班级内部自动完成?

3 个答案:

答案 0 :(得分:4)

您只需在第一次调用get_baz时缓存值。

class ExampleClass:
    _baz = None

    def __init__(self, foo):
        self.foo = foo

    def calc_bar(self):
        baz = self.get_baz()
        return baz * self.foo

    @classmethod
    def get_baz(cls):
        if cls._baz is None:
            cls._baz = <result of query>
        return cls._baz

答案 1 :(得分:1)

一种选择是将baz定义为None,然后仅在get_baz()的情况下使baz更新None

class ExampleClass:
    baz = None
    def calc_bar(self):
        return self.get_baz() * 2
        
    @classmethod
    def get_baz(cls):
        if cls.baz is None:
           cls.baz = 'hello' # <result of query>
        return cls.baz

ec = ExampleClass()

print(ec.baz)
# Output: None

print(ec.calc_bar())
# Output: hellohello

print(ec.baz)
# Output: hello

答案 2 :(得分:1)

class ExampleClass():

    def __new__(cls, *args, **kwargs):  # Singleton
        if cls.foo is None:
            cls.foo = ...
        return super(ExampleClass, cls).__new__(cls)
    # the rest is as usual

此方法的优点是可以在foo上访问__init__,否则它类似于其他答案