Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 访问类嵌套属性的有效方法_Python_Class_Nested Attributes - Fatal编程技术网

Python 访问类嵌套属性的有效方法

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:

假设我们有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:
    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中使用它,尽管如此,我将来可能还需要对任何类实例使用这样的函数,所以,谢谢:)没问题:-)