Типовое литье в питоне - PullRequest
       4

Типовое литье в питоне

2 голосов
/ 05 февраля 2011

Я посмотрел на аналогичный вопрос на SO, но ни один из них не ответил на мою проблему. Например Как вы приводите экземпляр к производному классу? . Но ответ, похоже, не тот, который я хочу.

Вот моя ситуация. У меня есть структура классов, как в Django

class Base:
     ...some stuff...

class Derived(Base):
     ...some more stuff...

Теперь, когда я делаю несколько запросов в Django, я всегда получаю объекты базового класса.

 baseobj = get_object_or_404(Base, id = sid)

Во время выполнения я также могу столкнуться с «производными» объектами, которые имеют некоторые дополнительные свойства. Я могу выяснить, является ли объект базовым или производным (в объекте базового класса достаточно информации). Но как мне получить доступ к тем дополнительным полям, которые присутствуют только в классе Derived. Я не в состоянии опустить "База" -> "Производная". Как мне справиться с этим?

EDIT:

Я понял проблему. Django хранит «дополнительные свойства» класса Derived в отдельной таблице. Следовательно, проблема возникла из-за этой строки кода.

baseobj = get_object_or_404(Base, id = sid)

baseobj всегда будет иметь базовый класс и не будет иметь никаких свойств класса Derived. Мне нужно сделать дополнительный запрос, чтобы получить объект класса Derived.

baseobj = get_object_or_404(Base, id = sid)
if baseobj.isDerivedType:
      derivedobj = get_object_or_404(Derived, id = sid)

Ответы [ 4 ]

9 голосов
/ 05 февраля 2011

Этот вид наследования в Джанго-ланде для меня пахнет многостоловым наследованием . Согласно документу, при условии, что все правильно подключено, вы должны сделать:

baseobj.derived    # note: small 'd'
2 голосов
/ 05 февраля 2011

Как правило, я бы сказал, что в такой ситуации типично использовать условие try-кроме

class thing1(object):
    def __init__(self):
        self.a = 5

class thing2(thing1):
    def __init__(self):
        super(thing2, self).__init__()
        self.b = 6

t = thing1()
try: 
    print(t.b)
except AttributeError: 
    print("handling the exception")

РЕДАКТИРОВАТЬ: Но правильно ли я понимаю ваш вопрос?Ответ: Нет. Упс!

РЕДАКТИРОВАТЬ2: Тем не менее, кажется, что некоторые изменения в вышеупомянутом блоке try-кроме были бы лучше, чем двойной доступ к базе данных, как предлагает ваш отредактированный вопрос.

1 голос
/ 05 февраля 2011

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

Проблема с проверкой, является ли ваш объект isDerivedType, заключается в том, что при добавлении другого производного класса вам придется изменить свою базу, чтобы выполнять проверки для нового производного типа. Это нарушает модель объектно-ориентированного программирования. Если кто-то другой использует ваш код и решит унаследовать ваш класс, он не сможет эффективно это сделать.

Старайтесь максимально работать с производными типами. Точка наследования в Django заключается в том, чтобы разрешить повторное использование кода и обмен данными между классами - , а не скрытие информации.

0 голосов
/ 21 мая 2012

Использовать "производную" версию производного класса:

class Base:
     base_attribute

class Derived(Base):
     derived_attribute

baseobj = get_object_or_404(Base, id = sid)
if baseobj.isDerivedType:
     print baseobj.derived.derived_attribute
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...