如何在其中保存类的实例';在Python中,是否将自己的类作为类变量?
我试图定义一个类,它有一个自身的实例作为类变量,这样我就可以在所有地方引用它的一个公共实例 我怎样才能让这样的东西发挥作用如何在其中保存类的实例';在Python中,是否将自己的类作为类变量?,python,python-3.x,Python,Python 3.x,我试图定义一个类,它有一个自身的实例作为类变量,这样我就可以在所有地方引用它的一个公共实例 我怎样才能让这样的东西发挥作用 class Point(): ORIGIN = Point() def __init__(self, x=0, y=0): self.x = x self.y = y p0 = Point.ORIGIN p1 = Point(3,4) distance = (p1.x*p1.x + p1.y*p1.y) ** .5 print(distance
class Point():
ORIGIN = Point()
def __init__(self, x=0, y=0):
self.x = x
self.y = y
p0 = Point.ORIGIN
p1 = Point(3,4)
distance = (p1.x*p1.x + p1.y*p1.y) ** .5
print(distance)
创建类后,可以添加类属性:
class Point():
def __init__(self, x=0, y=0):
self.x = x
self.y = y
Point.ORIGIN = Point()
您也可以让它工作,以便通过描述符惰性地创建源代码,或者您也可以使用元类做一些有趣的事情——但这似乎不值得您花时间。您可以使用元类:
>>> class SingletonMeta(type):
... def __init__(cls, name, bases, dct):
... cls.ORIGIN = cls()
...
>>> class Point(metaclass=SingletonMeta):
... def __init__(self, x=0, y=0):
... self.x = x
... self.y = y
...
>>> p0 = Point.ORIGIN
>>> p1 = Point(3,4)
>>> p0
<__main__.Point object at 0x110b7e7b8>
>>> p0.x, p0.y
(0, 0)
>>类SingletonMeta(类型):
... 定义初始值(cls、名称、基数、dct):
... cls.ORIGIN=cls()
...
>>>类点(元类=SingletonMeta):
... 定义初始化(self,x=0,y=0):
... self.x=x
... self.y=y
...
>>>p0=原点
>>>p1=点(3,4)
>>>p0
>>>p0.x,p0.y
(0, 0)
只需创建表示所需值的类变量,而不是将这些值封装在实例中:
class Point:
x = 0
y = 0
def __init__(self, x=0, y=0):
self.x = x
self.y = y
x,y = Point.x, Point.y
p1 = Point(3,4)
distance = ((p1.x-x)**2 + (p1.y-y)**2) ** .5
print(distance) # prints 5.0
或者,更好的是:
class Point:
x = 0
y = 0
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def distance(self, other=None):
if other is None:
x,y = Point.x, Point.y
else:
x,y = other.x, other.y
return ((self.x-x)**2 + (self.y-y)**2) ** .5
然后你可以这样做:
>>> p1 = Point(3,4)
>>> p1.distance()
5.0
>>> p1.distance(Point(3,5))
1.0
如果你需要一个“公共实例”,你可能在寻找静态变量/方法。旁注:你正在重新发明
数学。hypot
,除了你的不太准确。这看起来是一件很有价值的事情。你能告诉我们更多关于元类是如何工作的,或者它的构造函数何时被调用的吗?@Joshordorff——元类构造函数是在类被创建时被调用的。e、 g.在本例中,调用SingletonMeta.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuSingletonMeta.\uuuu init\uuuu
在创建点之后立即调用。感谢您的实际解决方案!我很失望,在一个可能很长的类定义之后,附加ORIGIN必须发生在最底层,但这似乎是最好的方法,不会变得更复杂。