如何使用 属性()
How to use property()
我在如何实施 属性 来保护属性方面遇到了问题。
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def set_x(self, x):
if '_x' in dir(self):
raise NotImplementedError("Cannot change x coordinate")
else:
self._x = x
def get_x(self):
return self._x
#I beleive my mistake is here. I'm not sure if I'm implementing this correctly
x = property(get_x, set_x, None, None)
所以我想阻止任何用户更改 x 坐标。我的问题是,如何让 python 将用户重定向到 set_x() 和 get_x() 方法?我已经在终端中尝试 运行 这段代码,每当我应用以下代码时,点都会改变。
p = point(3, 4)
p.x = 5 #x is now 5
以下代码适用于 python2.x 和 python3.x:
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
def set_x(self, x):
if '_x' in dir(self):
raise NotImplementedError("Cannot change x coordinate")
else:
self._x = x
def get_x(self):
return self._x
x = property(get_x, set_x, None, None)
p = Point(2, 3)
print(p.x) # 2
p.x = 6 # NotImplementedError
几乎所有我所做的都是从 object
继承(让它在 python2.x 上工作)并使用名称 Point
而不是 point
(这将以前是NameError
)。
您还可以做一些其他事情来稍微清理一下(例如,khelwood 建议只写 getter -- 或者 DSM 建议使用 hasattr
而不是 '_x' in dir(self)
).
请注意,如果您真的只想要一个带有 x
和 y
参数的类型并且您希望它是不可变的——也许您应该考虑使用 colledctions.namedtuple
from collections import namedtuple
Point = namedtuple('Point', 'x,y')
p = Point(2, 3)
p.x # 2
p.y # 3
p.x = 6 # AttributeError: can't set attribute
你只需要这么多:
class Point:
def __init__(self, x, y):
self._x = x
self.y = y
def get_x(self):
return self._x
x = property(get_x)
您可以在 init
中设置隐藏字段 self._x
,然后您根本不需要 x
的 setter。并且有 get_x
return self._x
而不是 self.x
所以它不会尝试调用自己。
您可以使用 @property
装饰器来更简洁地完成此操作。
class Point:
def __init__(self, x, y):
self._x = x
self.y = y
@property
def x(self):
return self._x
我在如何实施 属性 来保护属性方面遇到了问题。
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def set_x(self, x):
if '_x' in dir(self):
raise NotImplementedError("Cannot change x coordinate")
else:
self._x = x
def get_x(self):
return self._x
#I beleive my mistake is here. I'm not sure if I'm implementing this correctly
x = property(get_x, set_x, None, None)
所以我想阻止任何用户更改 x 坐标。我的问题是,如何让 python 将用户重定向到 set_x() 和 get_x() 方法?我已经在终端中尝试 运行 这段代码,每当我应用以下代码时,点都会改变。
p = point(3, 4)
p.x = 5 #x is now 5
以下代码适用于 python2.x 和 python3.x:
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
def set_x(self, x):
if '_x' in dir(self):
raise NotImplementedError("Cannot change x coordinate")
else:
self._x = x
def get_x(self):
return self._x
x = property(get_x, set_x, None, None)
p = Point(2, 3)
print(p.x) # 2
p.x = 6 # NotImplementedError
几乎所有我所做的都是从 object
继承(让它在 python2.x 上工作)并使用名称 Point
而不是 point
(这将以前是NameError
)。
您还可以做一些其他事情来稍微清理一下(例如,khelwood 建议只写 getter -- 或者 DSM 建议使用 hasattr
而不是 '_x' in dir(self)
).
请注意,如果您真的只想要一个带有 x
和 y
参数的类型并且您希望它是不可变的——也许您应该考虑使用 colledctions.namedtuple
from collections import namedtuple
Point = namedtuple('Point', 'x,y')
p = Point(2, 3)
p.x # 2
p.y # 3
p.x = 6 # AttributeError: can't set attribute
你只需要这么多:
class Point:
def __init__(self, x, y):
self._x = x
self.y = y
def get_x(self):
return self._x
x = property(get_x)
您可以在 init
中设置隐藏字段 self._x
,然后您根本不需要 x
的 setter。并且有 get_x
return self._x
而不是 self.x
所以它不会尝试调用自己。
您可以使用 @property
装饰器来更简洁地完成此操作。
class Point:
def __init__(self, x, y):
self._x = x
self.y = y
@property
def x(self):
return self._x