Pythonでは、Bar内から別のオブジェクトBarを含むオブジェクト(Fooなど)を取得できますか?これが私の意味の例です
class Foo(object):
def __init__(self):
self.bar = Bar()
self.text = "Hello World"
class Bar(object):
def __init__(self):
self.newText = foo.text #This is what I want to do,
#access the properties of the container object
foo = Foo()
これは可能ですか?ありがとう!
次のように、Barオブジェクトへの参照を渡します。
class Foo(object):
def __init__(self):
self.text = "Hello World" # has to be created first, so Bar.__init__ can reference it
self.bar = Bar(self)
class Bar(object):
def __init__(self, parent):
self.parent = parent
self.newText = parent.text
foo = Foo()
Edit:@thomleoによって指摘されているように、これはガベージコレクションで問題を引き起こす可能性があります。提案されたソリューションは http://eli.thegreenplace.net/2009/06/12/safely-using-destructors-in-python/ に配置され、次のようになります。
import weakref
class Foo(object):
def __init__(self):
self.text = "Hello World"
self.bar = Bar(self)
class Bar(object):
def __init__(self, parent):
self.parent = weakref.ref(parent) # <= garbage-collector safe!
self.newText = parent.text
foo = Foo()
bar内から別のオブジェクトBarを含むFooなどのオブジェクトを取得することはできますか?
「自動的に」ではなく、言語はそのように構築されていないため、特に、言語はFooが存在することを保証する方法がないように構築されています。
つまり、いつでも明示的に行うことができます。 Pythonの他のすべての識別子と同様に、属性は単なる名前であり、データのストレージスペースではありません。したがって、BarインスタンスにFooインスタンスであるfoo
属性を手動で割り当てさせたり、同時にその逆をさせたりすることを妨げるものは何もありません。
はい、可能です。オブジェクトの作成時にコンテナー参照を渡さなくても、つまり、オブジェクトがクラス属性の場合です。オブジェクトは記述子プロトコルを実装する必要があります(__get__()
を使用):
class ChildName(SimpleNamespace):
def __get__(self, instance, owner):
# instance is our parent
return f'I am {self.name}, my parent is {instance.name}.'
class ChildDiff(SimpleNamespace):
@property
def diff(self):
return self.born - self.parent.born
def age_diff(self):
return f'I am {self.diff} years older than {self.parent.name}.'
def __get__(self, instance, owner):
self.parent = instance # XXX: weakref?
return self # expose object to be able call age_diff() etc.
class Parent(SimpleNamespace):
child_name = ChildName(name='Bar')
child_diff = ChildDiff(born=42)
parent = Parent(name='Foo', born=23)
print(parent.child_name) # ... I am Bar, my parent is Foo.
print(parent.child_diff.age_diff()) # ... I am 19 years older than Foo.