【问题标题】:Accessing the class that created another class访问创建另一个类的类
【发布时间】:2019-12-16 23:42:13
【问题描述】:

我正在创建一个包含很多嵌套类的包。想象一下 2 类:House 和 Roof。 House 可以实例化一个屋顶,也可以存储它,改变它的属性,调用它的方法。但是反过来的问题呢? Roof 对象能否确定它是否由 House 实例化并发现有关该父对象的任何信息?在这个伪代码中,我假设的父 House 对象是 <parent>

class House(object):
    def __init__(self, style:str):
        self.style = style
        self.roof = Roof()

class Roof(object):
    def __init__(self):
        self.type = None
        if <parent>:
            if <parent>.style = 'Rambler':
                self.type = 'Open Gable'
            elif <parent>.style = 'Bungalow':
                self.type = 'Hip'

h = House('Bungalow')

这只是对其工作原理的大胆猜测,但我正在测试是否存在父类,然后想要访问它的属性。这可能吗?

我知道我可以将一个参数(房子的风格)传递给屋顶的__init__,但我要解决的真正问题涉及更多的属性,这是我想要避免的。

我已经看到通过让 Roof 类存储属性 __house 来解决这个问题的包,我认为这是为了解决这个问题。我假设 House 将 self 传递给 Roof 构造函数,但这似乎需要更多编码,我也想知道它是否复制了程序存储的对象。

谢谢!

【问题讨论】:

  • “我假设 House 将 self 传递给 Roof 构造函数” - 仅当它被显式传递时。 Roof 对象没有其他方法来获取对 House 对象的引用,除非明确给出该引用。
  • Python 具有很好的自省功能(您可以使用该语言来了解程序的当前状态和有关变量的元信息),这个答案应该可以满足您的需求 - 这可能会被关闭作为骗子:stackoverflow.com/questions/2611892/…
  • 也许使用元类或其他东西,但没有明确传递Roof,我认为你正在寻找错误的解决方案。
  • @mgrollins 这不是关于继承,这基本上是关于找出堆栈上一级发生的事情。基本上,函数的调用者是谁。
  • 哦,对了。好吧,也许将Roof 和其他人设置为inner class 会建立在该反向链接中?

标签: python class object instantiation


【解决方案1】:

生成的类有一些技术上的hacky方法可以找出谁调用了它的构造函数,但这会很混乱。

在您的类设计中,您可以使 Roof 在其构造函数中传递对 House 的引用

class Roof:
    def __init__(self, house):
        self.house = house

但是,在查看您的代码时,我看到了“代码异味”。当设置屋顶样式的方式取决于房屋的类型时,您将这两个类非常紧密地联系在一起。

“更清洁”的方式是允许使用屋顶创建者想要的任何样式创建屋顶:

class Roof:
    def __init__(self, style):
        self.style = style

然后在House 中,您可以选择哪种风格的屋顶与哪种风格的房子相配。这样一来,屋顶就不需要引用回房子了。

【讨论】:

  • 感谢您的回复。我的包中的对象非常紧密地集成在一起,所以我不太担心创建依赖项。你有任何“hacky”解决方案的链接吗?关于你的想法,可能有很多属性需要传递,所以第一个代码块会简单得多。
  • 好吧,我肯定会提倡明确说明依赖关系。因此,如果您认为您的 Roof 类确实需要对生成它的 House 类的引用,那么通过构造函数(第一个代码块)将其传入是可行的方法。 “hacky”解决方案类似于stackoverflow.com/questions/900392/…
  • 但我也鼓励你研究一下什么是“好的”面向对象设计。单一职责原则、耦合与内聚、得墨忒耳定律等概念。
  • 谢谢,我认为在子构造函数中传递对父对象的引用是有意义的。我做了一些测试,它只存储对它的引用,所以没有重复。房屋/屋顶示例只是问题的简化。我实际上正在为我使用的 API 创建一些类,父对象代表托管服务,子对象是存储在那里的东西。出于某种原因,父母需要很长时间才能进行身份验证和打开连接(第 3 方,所以我无法控制)。一旦我与父母建立了联系,我不想继续为每个孩子重新创建它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多