在学习Python时,通过典型的Point类示例,我注意到由于某种原因,我不能拥有与类相同类型的类级别(静态变量).例如
class Point:
ORIGIN = Point() # doesn't work
def __init__(self, x=0, y=0):
self.x = x
self.y = y
Run Code Online (Sandbox Code Playgroud)
虽然在Java中也是如此:
class Point {
public static void main(final String[] args) { }
private static final Point ORIGIN = new Point(0, 0);
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
Run Code Online (Sandbox Code Playgroud)
问题是:有没有办法在Python中实现相同的目标.现在我依赖于模块级变量,我不喜欢那个解决方案.还有,有什么理由说它不能在课堂上完成吗?
Ign*_*ams 11
class Point(object):
pass
Point.ORIGIN = Point()
Run Code Online (Sandbox Code Playgroud)
事后分配:
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
Point.ORIGIN = Point()
Run Code Online (Sandbox Code Playgroud)
您不能创建类的实例,直到实际创建该类,也就是在评估类主体之后(注意:它像普通 Python 代码一样执行)。
您的 Java 示例也是如此:ClassLoader 创建Point类,然后从static字段执行代码。
Python 中类加载器的粗略等价物是元类,因此您可以执行以下操作:
def class_with_static(name, bases, body):
static_block = body.pop("__static__", None)
klass = type(name, bases, body)
if static_block:
static_block(klass)
return klass
class Point(object):
__metaclass__ = class_with_static
def __static__(cls):
cls.ORIGIN = cls()
def __init__(self, x=0, y=0):
self.x = x
self.y = y
assert isinstance(Point.ORIGIN, Point)
assert Point.ORIGIN.x == Point.ORIGIN.y == 0
assert not hasattr(Point, "__static__")
Run Code Online (Sandbox Code Playgroud)
当然,这会产生其他一些后果,例如: 的所有子类都Point将拥有ORIGIN自己的属性。所以你可能只想像其他人一样去做:)