Class Instance As Static Attribute
Solution 1:
The expression A()
can't be run until the class A
has been defined. In your first block of code, the definition of A
is not complete at the point you are trying to execute A()
.
Here is a simpler alternative:
classA:def__init__(self):
...
A.static_attribute = A()
Solution 2:
When you define a class, Python immediately executes the code within the definition. Note that's different than defining a function where Python compiles the code, but doesn't execute it.
That's why this will create an error:
classMyClass(object):
a =1 / 0
But this won't:
def my_func():
a =1 / 0
In the body of A
's class definition, A
is not yet defined, so you can't reference it until after it's been defined.
There are several ways you can accomplish what you're asking, but it's not clear to me why this would be useful in the first place, so if you can provide more details about your use case, it'll be easier to recommend which path to go down.
The simplest would be what khelwood
posted:
classA(object):
pass
A.static_attribute =A()
Because this is modifying class creation, using a metaclass could be appropriate:
classMetaA(type):
def __new__(mcs, name, bases, attrs):
cls = super(MetaA, mcs).__new__(mcs, name, bases, attrs)
cls.static_attribute = cls()
return cls
classA(object):
__metaclass__ = MetaA
Or you could use descriptors to have the instance lazily created or if you wanted to customize access to it further:
classMyDescriptor(object):
def __get__(self, instance, owner):
owner.static_attribute = owner()
return owner.static_attribute
classA(object):
static_attribute = MyDescriptor()
Solution 3:
Using the property
decorator is a viable approach, but it would need to be done something like this:
classA:
_static_attribute = None @propertydefstatic_attribute(self):
if A._static_attribute isNone:
A._static_attribute = A()
return A._static_attribute
def__init__(self):
pass
a = A()
print(a.static_attribute) # -> <__main__.A object at 0x004859D0>
b = A()
print(b.static_attribute) # -> <__main__.A object at 0x004859D0>
Solution 4:
You can use a class decorator:
defset_static_attribute(cls):
cls.static_attribute = cls()
return cls
@set_static_attribute classA:
pass
Now:
>>>> A.static_attribute
<__main__.A at 0x10713a0f0>
Applying the decorator on top of the class makes it more explicit than setting static_attribute
after a potentially long class definition. The applied decorator "belongs" to the class definition. So if you move the class around in your source code you will more likely move it along than an extra setting of the attribute outside the class.
Post a Comment for "Class Instance As Static Attribute"