【问题标题】:Can an attributed object access its object's other attributes in python?属性对象可以在 python 中访问其对象的其他属性吗?
【发布时间】:2020-11-20 14:31:23
【问题描述】:

我是 python 新手,如果这太糟糕了,请提前道歉。

假设我动态地使一个对象成为另一个对象的属性。 分配为属性对象是否可以在不继承作为参数传递的情况下访问分配给对象的其他属性?

例如:-

class human:
    def __init__(self):
        self.health = 100

class fire:
    def __init__(self):
        self.fire = 10
    def damage(self):
        ????.health -= self.fire   #can i do anything to get bill's health?

bill = human()
bill.fired = fire()
bill.fired.damage()   #the fired object wants to know the bill object's health

我知道我可以将比尔的健康状况作为参数传递给损坏函数:-

class human:
    def __init__(self):
        self.health = 100

class fire:
    def __init__(self):
        self.fire = 10
    def damage(self, obj):
        obj.health -= self.fire

bill = human()
bill.fired = fire()

print bill.health

bill.fired.damage(bill)   #now the fired object knows bill's health

print bill.health   #works fine

但是有没有其他方法或者这是一个死胡同?除了继承。 (我用的是python v2.7,当然也想知道v3的解决方案)

如果这个问题太糟糕或已被回答,我再次道歉。 我试图阅读这个Can an attribute access another attribute?,但我无法理解它,它太复杂了。如果我用谷歌搜索这个问题,结果只会导致“如何访问对象属性”,例如这个https://www.geeksforgeeks.org/accessing-attributes-methods-python/。而这个How to access attribute of object from another object's method, which is one of attributes in Python? 使用继承。

【问题讨论】:

  • 由于这是 Python,可能有一种(有些复杂的)方法可以做到这一点,但如果您当前的结构满足这种需求,您应该重新考虑您的代码结构。
  • 我一直在尝试重组,但最终结果要么是固定函数、变得模糊复杂的类,要么是我使用字典或列表来存储某些数据的权衡。我对使用某些数据的字典或列表以及类感到不舒服,如果我这样做可以吗?我不知道这是不是一种不好的做法。

标签: python python-2.7 class oop object


【解决方案1】:

是的,您可以在创建时将human 传递给fire,因为它们似乎相互关联:

class Human:
    def __init__(self):
        self.health = 100

class Fire:
    def __init__(self, human):
        self.fire = 10
        self.human = human
    def damage(self):
        self.human.health -= self.fire

bill = Human()
bill.fired = Fire(bill)
bill.fired.damage()   #the fired object damages bill object's health

【讨论】:

    【解决方案2】:

    我不确定您的目标是什么,但正如我所提到的,您的问题在我看来就像是代码异味(表明某些事情不正确)。

    假设您希望 human 实例着火(即创建一个 fire 实例)然后推断出火损害了它们的健康,请考虑以下重构:

    class human:
        def __init__(self):
            self.health = 100
            self.fire = None
    
        def set_on_fire(self):
            self.fire = fire()
    
        def suffer_burn_damage(self):
            if self.fire is not None:
                self.health -= self.fire.damage
    
    class fire:
        def __init__(self):
            self.damage = 10
    
    bill = human()
    print(bill.health)  # output: 100
    bill.set_on_fire()
    bill.suffer_burn_damage()
    print(bill.health)  # output: 90
    

    这样,您首先不需要fire 实例来了解human 的健康状况。 human 的“工作”是跟踪它是否被烧毁,以及何时推断其自身的损坏。

    这在更抽象的含义上也很有意义 - 这是使用 OOP 的要点之一。现实生活中的火具有一定的能量。着火的人的“健康”将从火所具有的任何能量中推断出来。火灾本身与了解人类健康或其他任何事情无关。

    【讨论】: