访问 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' 开头的属性。