Reputation: 989
Consider the following simple class:
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>
I then use it with something like the following:
from module1 import ExampleClass
foo = 10
myobj = ExampleClass(foo)
bar = myobj.calc_bar()
The way this is currently constructed the database is queried every time I call the calc_bar
method.
How would I turn the output of the get_baz
method into a class attribute that is set only once for the class?
I can do it manually via:
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()
Is there a way it can be done automatically from within the class?
Upvotes: 1
Views: 48
Reputation: 15738
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
The advantage of this method is that foo
is accessible at __init__
, otherwise it is similar to other answers
Upvotes: 1
Reputation: 25489
One option is to define baz
as None
, and then make get_baz()
update baz
only if it's 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
Upvotes: 1
Reputation: 530960
You can simply cache the value the first time get_baz
is called.
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
Upvotes: 4