Nano Hash - криптовалюты, майнинг, программирование

Получение контейнера/родительского объекта из Python

Можно ли в Python получить объект, скажем, Foo, который содержит другой объект, Bar, из самого Bar? Вот пример того, что я имею в виду

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()

Это возможно? Спасибо!


  • У вас опечатка; в Foo.__init__ self.bar = Foo() должно быть self.bar = Bar(). В противном случае вы получите бесконечный цикл (чтобы создать Foo, вам сначала нужно создать Foo). 29.05.2012

Ответы:


1

Передайте ссылку на объект 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()

Изменить: как указал @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()
28.05.2012
  • Спасибо, это работает. Единственная проблема, которую я вижу в этом, заключается в том, что когда я пытаюсь получить доступ ко многим объектам, я буду вызывать parent.parent.parent.etc. Есть ли более аккуратный способ сделать это? 29.05.2012
  • Если я не ошибаюсь, с этим тоже есть большая проблема. Когда вы попытаетесь сделать del foo, это не обязательно уничтожит его, поскольку ссылка на него все еще существует в атрибуте .parent Bar, который он содержит... 05.06.2013
  • @MichaelMcClenaghan, в этом случае вы можете просто повторять несколько раз вместо того, чтобы писать это вручную. Конечно, это зависит от структуры... 28.03.2014
  • Разве вам не нужно вызывать слабый ссылочный объект? self.newText = self.parent().text 21.07.2017
  • Моя ошибка, ответ использует parent.text (объект), а не self.parent.text (слабая ссылка) 11.01.2018

  • 2

    возможно ли получить объект, скажем, Foo, который содержит другой объект, Bar, из самого Bar?

    Не «автоматически», потому что язык построен не так, и, в частности, язык построен так, что нет никакого способа гарантировать, что Foo существует.

    Тем не менее, вы всегда можете сделать это явно. Атрибуты, как и любой другой идентификатор в Python, — это просто имена, а не место для хранения данных; так что ничто не мешает вам позволить экземпляру Bar иметь назначенный вручную атрибут foo, который является экземпляром Foo, и наоборот одновременно.

    29.05.2012

    3

    Да, это возможно. Даже без передачи ссылки на контейнер при создании объекта, т.е. если ваш объект является атрибутом класса. Ваш объект должен реализовать протокол дескриптора (иметь __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.
    
    09.07.2019

    4

    Как насчет использования наследования:

    class Bar(object):
        def __init__(self):
            self.newText = self.text
    
    class Foo(Bar):
        def __init__(self):
            self.txt = 'Hello World'
            Bar.__init__(self)
    
    foo = Foo()
    print foo.newText
    
    29.05.2012
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..