Python中的访问器/存储类 在C++中,我经常用“访问器”结构来分解大类,如下面的 struct Big { struct Coordinates { int x; int y; } coords; }
这避免了名称空间污染,使调用站点非常清晰,例如:Python中的访问器/存储类 在C++中,我经常用“访问器”结构来分解大类,如下面的 struct Big { struct Coordinates { int x; int y; } coords; },python,oop,Python,Oop,这避免了名称空间污染,使调用站点非常清晰,例如:big.coords.x这尤其有助于避免使用许多名为“set_x”的函数,而这些函数会变为“set.x” 我想在Python中做同样的事情,比如下面,但我想知道这是否被认为是好的Python风格 class Big: class Coordinates: x = 0 y = 0 coords = Coordinates() big.coords.x 如果您从未实例化过类,则完全可以仅对名称空间进行
big.coords.x代码>这尤其有助于避免使用许多名为“set_x”的函数,而这些函数会变为“set.x”
我想在Python中做同样的事情,比如下面,但我想知道这是否被认为是好的Python风格
class Big:
class Coordinates:
x = 0
y = 0
coords = Coordinates()
big.coords.x
如果您从未实例化过类,则完全可以仅对名称空间进行实例化:
class Colors:
class RGB:
Red = (255, 0, 0)
Green = (0, 255, 0)
Blue = (0, 0, 255)
class CMYK:
pass
color1 = Colors.RGB.Red
然而,这是不同的:
class Big:
class Coordinates:
x = 0
y = 0
coords = Coordinates()
在Big
类中实例化Coordinates
类对象,特别是在Big.coords
中
x
和y
在开始时对于每个坐标
对象实例都是0
。但它们也是类属性,而不是实例属性。这意味着它们在每个实例之间共享,直到您在实例中指定其中一个。然后该特定实例开始有自己的x
或y
。这与你所期望的完全不同。你应该这样做:
class Coordinates:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
class Big:
def __init__(self, coords=None):
self.coords = coords or Coordinates(0,0)
def __str__(self):
return "Big coords at x:{} y:{}".format(self.coords.x, self.coords.y)
big = Big()
print(big)
print(big.coords.x, big.coords.y)
point1 = Coordinates(1, 2)
big1 = Big(point1)
print(big1)
输出:
Big coords at x:0 y:0
0 0
Big coords at x:1 y:2
这样可以使一个实例包含另一种类型的实例。这也是使用包含而不是继承的一个示例
安排名称空间的另一种常见方法是,只在要导入的模块中组织名称
有关其他想法,请参阅。在类实例中存储另一个类的实例是一件正常而有用的事情。实际上,将另一个类的定义嵌套在using类中,没有那么多。。。您是否真的不可能使用<代码>坐标< /代码>实例独立于<代码>大< /代码>?在这个例子中,代码>坐标< /COD>绝对是更通用的,但请考虑包含的类是特定于<代码>大< /代码>类的东西。在这种情况下,完全限定名清楚地说明了它们之间的关系。在Python中,这样做并不常见。Big
的实例可能将Coordinates
的实例作为属性,但只有在特殊情况下,Coordinates
本身才是Big
的属性。仅仅因为坐标
仅由Big
使用,并不使其成为Big
的一部分。类不仅仅是语法。