Can a python class have a class variable of this same class?

101 Views Asked by At

I want my class to have a class variable whose value is of that same class:

class XY:
    Origin = XY(0,0)
    def __init__(self, x, y):
        self.x = x
        self.y = y

however, this fails with

    Origin = XY(0,0)
NameError: name 'XY' is not defined

Apparently, I can do

class XY:
    ...
XY.Origin = XY(0,0)

instead - is this really the right way?

3

There are 3 best solutions below

0
JonSG On

Would a "metaclass" work any better for you? Perhaps something like:

class XY_Meta(type):
    def __init__(cls, name, bases, dct):
        cls.Origin = cls(0, 0)

class XY(metaclass=XY_Meta):
    def __init__(self, x, y):
        self.x = x
        self.y = y

point = XY(10, 10)
print(point.x, point.y, point.Origin.x, point.Origin.y)

I think that might give you:

10 10 0 0
0
Chris On

I agree with anentropic's comment. Presumably your XY class lives within a file. This provides a namespace. Origin can then live within that namespace and be imported as a qualified or unqualified name as the user of that module sees fit.

% cat coords.py 
class XY:
    def __init__(self, x, y):
        self.x = x
        self.y = y

origin = XY(0, 0)

% python3
Python 3.9.6 (default, Mar 10 2023, 20:16:38) 
[Clang 14.0.3 (clang-1403.0.22.14.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import coords
>>> coords.origin
<coords.XY object at 0x11000a970>
>>> from coords import origin as xy_origin
>>> xy_origin
<coords.XY object at 0x11000a970>
0
Sherstnyov On

Short answer is - yes, it's the right way. I would add a type hint for readability:

class ClassName:
    Origin: 'ClassName'

There is actually a similar question Class variables of same type as the class. Some solutions are over-complicated, and I can't imagine use cases for them really.