Are there Python versions that allow defining your class like this:
class Foo:
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
and then adding class attributes
, such as BAR_1, BAR_2
, etc.:
class Foo:
BAR_1 = ...
BAR_2 = ...
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
which are actually "special cases of Foo
", such as:
class Foo:
BAR_1 = Foo(4, 9, 16)
BAR_2 = Foo(2, 3, 5)
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
so that, in my code, I can either make my own Foos
or get common, predefined Foos
by working directly with Foo.BAR_1
and Foo.BAR_2
?
The code above obviously does not work, otherwise I would not post the question ( Foo
is an unresolved reference when defining BAR_1
and BAR_2
). I found a trick on SO how to sort-of achieve this -> defining a custom ClassProperty
class:
class ClassProperty(object):
def __init__(self, f):
self.f = f
def __get__(self, obj, owner):
return self.f(owner)
which then allows me to define Foo
as
class Foo:
@ClassProperty
def BAR_1(cls):
return Foo(4, 9, 16)
@ClassProperty
def BAR_2(cls):
return Foo(2, 3, 5)
...
and that works, but the issue is that Foo.__init__
is called everytime whenever Foo.BAR_1
or Foo.BAR_2
is retrieved, which can be useful in certain situations (precisely those where you always want separate instances), but in the special case where Foo
is simply a messenger class which is coincidentally hard to load (like a result of a computation for example), this solution is unfeasible. I'd like for the constructor of Foo
to be called exactly once for BAR_1
, exactly once for BAR_2
(ideally lazily, during the first retrieval, that would be fantastic), and after that it would only return the created instances. So, is there a way to do this?
I use Python 3.8.6
.
During the time I composed the question body, I figured out I can just define Foo
like this:
class Foo:
@ClassProperty
def BAR_1(cls):
if not hasattr(cls, '_Foo__BAR_1'):
cls.__BAR_1 = Foo(4, 9, 16)
return cls.__BAR_1
@ClassProperty
def BAR_2(cls):
if not hasattr(cls, '_Foo__BAR_2'):
cls.__BAR_2 = Foo(2, 3, 5)
return cls.__BAR_2
Now, I can call Foo.BAR_X
for retrieval of a defined Foo.__BAR_X
which is actually an instance of Foo
, which is always created only once.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.