Python 访问类嵌套属性的有效方法
假设我们有5个python类X1、X2、X3、X4、X5和以下代码:Python 访问类嵌套属性的有效方法,python,class,nested-attributes,Python,Class,Nested Attributes,假设我们有5个python类X1、X2、X3、X4、X5和以下代码: class Schedule: def __init__(self): pass class DateBound: def __init__(self): self.attr3 = Schedule() class Behavior: def __init__(self): self.attr2 = DateBound() class Host:
class Schedule:
def __init__(self):
pass
class DateBound:
def __init__(self):
self.attr3 = Schedule()
class Behavior:
def __init__(self):
self.attr2 = DateBound()
class Host:
def __init__(self):
self.attr1 = Behavior()
class PeriodController:
def __init__(self):
self.attr0 = Host()
现在假设PeriodController中的函数需要访问类DateBound的attr3:
class PeriodController:
def __init__(self):
self.attr0 = ()
def example_function(self):
return self.attr0.attr1.attr2.attr3
在这种情况下,我如何有效地访问attr3?我并不反对像示例_函数()那样访问它,但它似乎不正确,因为重复了attr0.attr1。。。属性
简单地说,这个实现的概念是主机有一个Bahavior,该Bahavior定义了他应该在什么时候连接到服务器
DateBound类是存在的,因为有时主机可以在与其正常的行为不同的时间连接到服务器,但它确实是好主机,因此没有使用DateBound实例指定主机的定期连接时间
日期绑定有一个时间表,其中包含日期绑定实例的时间,因此主机应该连接的时间。
最后,PeriodController控制主机是否根据其正常行为连接,因此PeriodController需要访问self.attr3您可以使用递归:
class X5:
def __init__(self):
self.attr0 = X4()
def example_function(self, count = 1):
if count == 4:
return self.attr0
self.attr0 = getattr(self.attr0, f'attr{count}')
return self.example_function(count+1)
print(X5().example_function())
输出:
<__main__.X1 object at 0x1012cc278>
<X1>
将\uuuu repr\uuuu
方法添加到每个类中可以更容易地可视化:
class X1:
...
def __repr__(self):
return f'<{self.__class__.__name__}>'
print(X5().example_function())
X1类:
...
定义报告(自我):
返回f“”
打印(X5().示例_函数())
输出:
<__main__.X1 object at 0x1012cc278>
<X1>
您可以使用递归:
class X5:
def __init__(self):
self.attr0 = X4()
def example_function(self, count = 1):
if count == 4:
return self.attr0
self.attr0 = getattr(self.attr0, f'attr{count}')
return self.example_function(count+1)
print(X5().example_function())
输出:
<__main__.X1 object at 0x1012cc278>
<X1>
将\uuuu repr\uuuu
方法添加到每个类中可以更容易地可视化:
class X1:
...
def __repr__(self):
return f'<{self.__class__.__name__}>'
print(X5().example_function())
X1类:
...
定义报告(自我):
返回f“”
打印(X5().示例_函数())
输出:
<__main__.X1 object at 0x1012cc278>
<X1>
虽然Ajax打败了我,但我正在开发一个更出色的解决方案:
def examplefunction(startObject, differenceInX):
for _ in range(differenceInX + 1):
startObject = getattr(startObject, (any(item.startswith('attr') for item in dir(startObject))[0])
return startObject
这应该在任何类之外定义
用法:
在这种情况下,startObject
将是X5()
的一个实例,而differenceInX
将是5-2=3
这个方法的优点是,它可以用于任何类,而不必重复定义它。请注意,
(dir(startObject)中的item的any(item.startswith('attr'))[0])
依赖于每个类只有一个以'attr'
开头的属性(在本例中为attr0/1/2/3/n
)。尽管Ajax打败了我,但我正在开发一个更好的解决方案:
def examplefunction(startObject, differenceInX):
for _ in range(differenceInX + 1):
startObject = getattr(startObject, (any(item.startswith('attr') for item in dir(startObject))[0])
return startObject
这应该在任何类之外定义
用法:
在这种情况下,startObject
将是X5()
的一个实例,而differenceInX
将是5-2=3
这个方法的优点是,它可以用于任何类,而不必重复定义它。请注意,
(dir(startObject)中的item的any(item.startswith('attr'))[0])
依赖于每个类只有一个以'attr'
开头的属性(在这种情况下,attr0/1/2/3/n)。每个类是否总是只有一个属性?如果X5
需要访问X2
中的属性,那么你的设计有问题了。每个类将有更多属性,但只有一个类型分别为X4(self.attr0)、X3(self.attr2)、X2(…)和X1(…)的属性。您可能是对的@chepner,但我不知道如何以任何其他方式实现该设计。从这样的人工示例中几乎不可能判断正确的设计应该是什么。如果没有更多的上下文,我看不出除了您已有的显式链之外,任何人都无法提出任何建议。每个类是否总是只有一个属性?如果X5
需要访问X2
中的属性,则说明您的设计有问题。否。每个类将有更多属性,但只有一个类型分别为X4(self.attr0)、X3(self.attr2)、X2(…)和X1(…)的属性。您可能是对的@chepner,但我不知道如何以任何其他方式实现该设计。从这样的人工示例中几乎不可能判断正确的设计应该是什么。如果没有更多的上下文,我看不出除了您已经拥有的显式链之外,还有人能提出任何建议。我怀疑属性是否真的通过attr3
命名为attr0
,并且此函数可能会关闭self.attr0
@user2357112,处理这个问题的最好方法可能就是常规的属性查找。然而,根据OP最近对其代码用例的描述,似乎确实存在一个attr3
,并且在我的选项中增加了确实存在最初列出的所有属性的可能性。我怀疑这些属性是否真的通过attr3
命名为attr0
,这个函数会关闭self.attr0@user2357112,这是一种可能性,并且可能处理这个问题的最好方法就是简单地进行常规属性查找。然而,根据OP最近对其代码用例的描述,似乎确实存在一个attr3
,在我的选项中,增加了确实存在最初列出的所有属性的可能性。我怀疑“每个类只有一个定义的属性”限制不太可能得到满足。我需要在类@Adi219中使用它,不过我将来可能还需要在任何类实例中使用这样的函数,所以,谢谢:)没问题:-)我怀疑“每个类只定义一个属性”限制不太可能得到满足。我需要在类@Adi219中使用它,尽管如此,我将来可能还需要对任何类实例使用这样的函数,所以,谢谢:)没问题:-)