Squeak.ru - шаблоны программирования

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

Я хотел бы знать, возможно ли это, и если да, то как получить доступ к атрибутам экземпляра "супер" класса при реализации композиции.


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

Я хочу иметь доступ к атрибуту «id» для экземпляра MiniVan непосредственно из объекта «дверь» (типа DoorElement).


Мой код

class Car:
    def __init__(self, _id):
        self.id = _id


class CarElement:
    def __init__(self, name):
        self.name = name

    def get_car_id(self):
        # Body which will access value of attribute "id"
        return car_id


class MiniVan(Car):
    def __init__(self, _id):
        super(MiniVan, self).__init__(_id)
        self.door = DoorElement('door')
        self.engine = EngineElement('engine')


class DoorElement(CarElement):
    def __init__(self, name):
        super(DoorElement, self).__init__(name)


class EngineElement(CarElement):
    def __init__(self, name):
        super(EngineElement, self).__init__(name)


def main():
    mini_van = MiniVan(123)
    id_from_door = mini_van.door.get_car_id()
    id_from_engine = mini_van.engine.get_car_id()
    print(id_from_door) # Expected output 123
    print(id_from_engine) # Expected output 123


if __name__ == '__main__':
    main()

Ожидается:

  • Дважды напечатано "123"

Что я пробовал:

  1. Передача обязательного атрибута при создании объекта

Я знаю, что мог бы просто определить метод init с передачей "car_id", но по некоторым причинам я хотел бы избежать этого, если это возможно. Если нет, я бы, наверное, просто пошел на это.

  1. установить атрибут класса, а затем вызвать его из класса CarElement внутри метода класса, например:
@classmethod
def get_id(cls):
    return Car.id

Но проблема с этим решением заключается в том, что у меня может быть много дочерних классов для класса автомобилей (MiniVan, Truck и т. д.), и я хочу, чтобы он все еще работал.

  1. Попытка использовать дескриптор
def __get__(self, instance, owner):
    return instance.id

Но я мог понять это неправильно, и на самом деле геттер (насколько я понимаю чистый код) должен возвращать экземпляр класса, а не какой-либо атрибут.


Дополнительная информация

  • Я ВСЕГДА буду использовать экземпляры CarElement (или дочерних классов) в качестве атрибутов экземпляров экземпляров Car (или дочерних классов) - другое использование будет рассматриваться как ошибка использования
  • Может быть много разных дочерних классов класса Car, но всегда в рамках наследования ( Car ‹- RacingCar(Car) ‹- FormulaOneCar(RacingCar) ), но без композиции
10.02.2019

  • Вы явно приложили много усилий, чтобы ответить на этот вопрос, но я бы предложил объяснить, что вы хотите получить сначала, и только затем показать нам ваши попытки решения. 10.02.2019
  • @Aran-Fey спасибо за этот отзыв. я уже редактировал вопрос 10.02.2019
  • Я предлагаю добавить общего «владельца» или «родителя» при создании Car Elements. Это позволяет вам иметь подкомпоненты, такие как дверная ручка автомобиля. автомобиль был бы просто корневым «объектом» без владельца. любое решение, основанное на отношениях класса, а не экземпляра, приведет к проблемам. 11.02.2019
  • @JLPeyret Не могли бы вы привести такой пример? Потому что я не уверен, действительно ли я следую твоей идее 12.02.2019

Ответы:


1

Чтобы ваш код работал, вам нужно инициализировать все CarElement с помощью car_id. В настоящее время ошибка, которую вы получаете, связана с отсутствием такой переменной в области действия метода. Мое представление об изменении таково:

class CarElement:
    def __init__(self, name, car_id):
        self.name = name
        self.car_id = car_id

    def get_car_id(self):
        # Body which will access value of attribute id
        return self.car_id

Я не вижу другого волшебного пути.

10.02.2019
  • Вместо того, чтобы хранить идентификатор автомобиля, лучше иметь ссылку на объект автомобиля. Таким образом, у вас есть доступ ко всем атрибутам и методам автомобиля. 10.02.2019
  • Да, я действительно видел, что этот вывод совершенно лишен смысла. Я знаю, что могу инициализировать объекты, передавая это значение в качестве атрибута, но вопрос заключался в том, есть ли другой способ получить к нему доступ. 10.02.2019
  • Как указано в ответе: нет. Ваши попытки выглядят как наложение объектной модели C++ на Python. Они разные и несовместимые. Объектная модель Python намного проще. 10.02.2019
  • @sophros, основываясь на моем опыте использования библиотеки page_objects точно так, как описано (представления в приложении используются как классы, наследуемые от PageObject, и элементы, определенные как экземпляры класса PageElement). Я бы сказал, что такой доступ возможен. В прикрепленной ссылке мы получаем доступ к атрибуту PageElement SeleniumWebDriver, который передается как атрибут для PageObject (self.w) непосредственно при вызове атрибута экземпляра представления. 10.02.2019
  • Новые материалы

    Угловая структура архитектуры
    Обратите внимание, что эта статья устарела, я решил создать новую с лучшей структурой и с учетом автономных компонентов: https://medium.com/@marekpanti/angular-standalone-architecture-b645edd0d54a..

    «Данные, которые большинство людей используют для обучения своих моделей искусственного интеллекта, поставляются со встроенным…
    Первоначально опубликовано HalkTalks: https://hacktown.com.br/blog/blog/os-dados-que-a-maioria-das-pessoas-usa-para-treinar-seus-modelos-de-inteligencia-artificial- ja-vem-com-um-vies-embutido/..

    Сильный ИИ против слабого ИИ: различия парадигм искусственного интеллекта
    В последние годы изучению и развитию искусственного интеллекта (ИИ) уделяется большое внимание и прогресс. Сильный ИИ и Слабый ИИ — две основные парадигмы в области искусственного интеллекта...

    Правильный способ добавить Firebase в ваш проект React с помощью React Hooks
    React + Firebase - это мощная комбинация для быстрого и безопасного создания приложений, от проверки концепции до массового производства. Раньше (знаете, несколько месяцев назад) добавление..

    Создайте API с помощью Python FastAPI
    Создание API с помощью Python становится очень простым при использовании пакета FastAPI. После установки и импорта вы можете создать приложение FastAPI и указать несколько конечных точек. Каждой..

    Веселье с прокси-сервером JavaScript
    Прокси-серверы JavaScript — это чистый сахар, если вы хотите создать некоторую общую логику в своих приложениях, чтобы облегчить себе жизнь. Вот один пример: Связь клиент-сервер Мы..

    Получить бесплатный хостинг для разработчиков | Разместите свой сайт за несколько шагов 🔥
    Статические веб-сайты — это веб-страницы с фиксированным содержанием и его постоянным содержанием. Но теперь статические сайты также обрабатывают динамические данные с помощью API и запросов...