处理具有子属性的类。以下代码是一个很好的做法/ Pythonic?如果没有,有什么建议吗?
目标
exp = ExCls()
prop1 = exp.subprop.prop1
exp.print_prop2()
## prop1 = 1
## prints 2
示例代码
class ExCls():
class subprop:
prop1 = 1
prop2 = 2
def print_prop2(self):
print self.subprop.prop2
答案 0 :(得分:2)
在大多数常见的高级语言中,点表示法用于表示命名空间。 Python也是如此。以下面的无用类为例:
>>> class UselessClass(object):
... @property
... def and_on(self):
... return self
... def forever(self):
... return "I can see into forever"
>>> this_goes_on = UselessClass()
>>> this_goes_on.and_on.and_on.and_on.and_on.and_on.forever()
'I can see into forever'
它正在做的就是返回它自己(UselessClass类型的实例化对象),它可以访问它自己的所有属性。
您的代码唯一的问题是,正如GingerPlusPlus指出的那样,您在subprop
的所有实例之间共享ExCls
。这可能是期望的,但(基于问题)也可能不是。以下是为什么这很糟糕的一个例子:
>>> test1 = ExCls()
>>> test2 = ExCls()
>>> test1.subprop.prop1
1
>>> test2.subprop.prop1 = 2
>>> test1.subprop.prop1
2
正如您所看到的,这通常不是您期望的行为。相反,你可能要做的是:
class ExCls(object):
def __init__(self):
class subprop:
prop1 = 1
prop2 = 2
self.subprop = subprop()
def print_prop2(self):
print(self.subprop.prop2)
总的来说,我强烈建议您回过头来阅读Python的课程,以及它们的工作原理。
答案 1 :(得分:1)
我建议使用正确的工具来完成工作 - 如果我希望我的subprop
只包含一些数据,我会使用types.SimpleNamespace
:
from types import SimpleNamespace
class Useless:
def __init__(self):
self.subprop = SimpleNamespace(prop1=1, prop2=2)
或者,它是足够接近的不可变兄弟,collections.namedtuple
:
from collections import namedtuple
class Useless:
Subprop = namedtuple('Subprop', 'prop1, prop2')
def __init__(self):
# two lines below does the same, choose more readable one
self.subprop = Subprop(1, 2)
self.subprop = Subprop(prop1=1, prop=2)
如果我想让它也包含一些方法,我会使用简单的自定义对象:
class Useless:
class Subprop:
def __init__(self, prop1, prop2):
self.prop1 = prop1
self.prop2 = prop2
def sum(self):
return self.prop1 + self.prop2
def __init__(self):
# two lines below does the same, choose more readable one
self.subprop = Subprop(1, 2)
self.subprop = Subprop(prop1=1, prop2=2)