访问 class 嵌套属性的有效方法
Efficient way to access class nested attrbibutes
考虑我们有 5 python classes 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:
def __init__(self):
self.attr1 = Behavior()
class PeriodController:
def __init__(self):
self.attr0 = Host()
现在假设 PeriodController 中的函数需要访问 class DateBound 的 attr3 :
class PeriodController:
def __init__(self):
self.attr0 = ()
def example_function(self):
return self.attr0.attr1.attr2.attr3
在这种情况下,我如何有效地访问 attr3?我不反对像 example_function() 那样访问它,但它似乎不正确,因为 attr0.attr1 ... attrn
简而言之,这个实现的概念是 Host 有一个 Bahavior 定义了他应该连接的时间到服务器。
DateBound class 存在,因为有时主机可以在与其正常行为不同的时间连接到服务器 时间,但它确实是好的主机,因此 none Host 的常规连接时间是使用 Datebound 实例指定的.
A DateBound 有一个 Schedule,其中包含 DateBound 实例具有的时间,因此应该连接 Host 的时间。
最后 PeriodController,控制 Host 是否根据其正常 Behavior 连接,因此 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>
打印X5().attr0.attr1.attr2.attr3)
得到同样的结果:
<__main__.X1 object at 0x1012cc278>
向每个 class 添加 __repr__
方法使可视化更容易:
class X1:
...
def __repr__(self):
return f'<{self.__class__.__name__}>'
print(X5().example_function())
输出:
<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
这应该在任何 class 之外定义。
用法:
在这种情况下,startObject
将是 X5()
的一个实例,而 differenceInX
将是 5 - 2 = 3。
这个方法的好处是它可以用于任何class而不需要重复定义它。请注意,(any(item.startswith('attr') for item in dir(startObject))[0])
依赖于每个 class(在本例中为 attr0/1/2/3/n
)只有一个以 'attr'
开头的属性。
考虑我们有 5 python classes 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:
def __init__(self):
self.attr1 = Behavior()
class PeriodController:
def __init__(self):
self.attr0 = Host()
现在假设 PeriodController 中的函数需要访问 class DateBound 的 attr3 :
class PeriodController:
def __init__(self):
self.attr0 = ()
def example_function(self):
return self.attr0.attr1.attr2.attr3
在这种情况下,我如何有效地访问 attr3?我不反对像 example_function() 那样访问它,但它似乎不正确,因为 attr0.attr1 ... attrn
简而言之,这个实现的概念是 Host 有一个 Bahavior 定义了他应该连接的时间到服务器。
DateBound class 存在,因为有时主机可以在与其正常行为不同的时间连接到服务器 时间,但它确实是好的主机,因此 none Host 的常规连接时间是使用 Datebound 实例指定的.
A DateBound 有一个 Schedule,其中包含 DateBound 实例具有的时间,因此应该连接 Host 的时间。 最后 PeriodController,控制 Host 是否根据其正常 Behavior 连接,因此 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>
打印X5().attr0.attr1.attr2.attr3)
得到同样的结果:
<__main__.X1 object at 0x1012cc278>
向每个 class 添加 __repr__
方法使可视化更容易:
class X1:
...
def __repr__(self):
return f'<{self.__class__.__name__}>'
print(X5().example_function())
输出:
<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
这应该在任何 class 之外定义。
用法:
在这种情况下,startObject
将是 X5()
的一个实例,而 differenceInX
将是 5 - 2 = 3。
这个方法的好处是它可以用于任何class而不需要重复定义它。请注意,(any(item.startswith('attr') for item in dir(startObject))[0])
依赖于每个 class(在本例中为 attr0/1/2/3/n
)只有一个以 'attr'
开头的属性。