与类类型相同的类变量
在学习Python的时候,我在玩一个典型的点(Point)类的例子时,发现有个问题:我不能在类里面定义一个和类类型相同的类变量(静态变量)。比如:
class Point:
ORIGIN = Point() # doesn't work
def __init__(self, x=0, y=0):
self.x = x
self.y = y
而在Java中,这样做是可以的:
class Point {
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;
}
}
我的问题是:有没有办法在Python中做到这一点?现在我只能依赖模块级别的变量,但我不太喜欢这个解决方案。另外,为什么在类里面就不能这样做呢?
4 个回答
9
事后再给它赋值:
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
Point.ORIGIN = Point()
16
在编程中,有时候我们会遇到一些问题,尤其是在使用某些工具或库的时候。这些问题可能会让我们感到困惑,不知道该怎么解决。比如,有人可能在使用一个特定的功能时,发现它没有按照预期工作。这种情况很常见,尤其是对于刚开始学习编程的人来说。
解决这类问题的第一步是要仔细阅读错误信息。错误信息通常会告诉你哪里出了问题,虽然有时候它们可能听起来很复杂,但其实可以从中找到线索。接下来,可以尝试在网上搜索这个错误,看看其他人是怎么解决的。
另外,查看官方文档也是个好主意。文档里面通常会有详细的说明和示例,帮助你更好地理解如何使用这个工具或库。如果还是找不到解决办法,可以考虑在编程社区发帖求助,描述你的问题和你尝试过的解决方法,通常会有人愿意帮助你。
总之,遇到问题时不要慌张,慢慢分析,寻找解决方案,编程的过程就是不断学习和解决问题的过程。
class Point(object):
pass
Point.ORIGIN = Point()
5
在你能创建一个类的实例之前,得先确保这个类已经被创建。这个过程是在类的内容被评估后进行的(注意:这就像正常的Python代码一样被执行)。
你提到的Java例子也是一样的:类加载器会创建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__")
当然,这样做会带来一些其他的后果,比如:所有Point
的子类都会有自己的ORIGIN
属性。所以你可能还是想像其他人那样做比较好 :)