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

Обновление до последней версии Gradle решает мою проблему:

classpath 'com.android.tools.build:gradle:0.13.+'
5
задан Community 23 May 2017 в 10:27
поделиться

5 ответов

Defining

def __init__(self):
    self.foo = 5

in Base makes foo a member (attribute) of the instance, not of the class. The class Base has no knowledge of foo, so there is no way to access it by something like a super() call.

This is not necessary, however. When you instanciate

foobar = Derived()

and the __init__() method of the base class calls

self.foo = 5

this will not result in the creation / overwriting of the attribute, but instead in Derived's setter being called, meaning

self.foo.fset(5)

and thus self._foo = 5. So if you put

return 1 + self._foo

in your getter, you pretty much get what you want. If you need the value that self.foo is set to in Base's constructor, just look at _foo, which was set correctly by the @foo.setter.

4
ответ дан 18 December 2019 в 13:18
поделиться

Жизнь проще, если вы используете делегирование вместо наследования. Это Python. Вы не обязаны наследовать от Base .

class LooksLikeDerived( object ):
    def __init__( self ):
        self.base= Base()

    @property
    def foo(self):
        return 1 + self.base.foo # always works

    @foo.setter
    def foo(self, f):
        self.base.foo = f

А как насчет других методов Base? Вы дублируете имена в LooksLikeDerived и просто

def someMethodOfBase( self, *args, **kw ):
    return self.base.someMethodOfBase( *args **kw )

Да, это не похоже на «СУХОЙ». Однако это предотвращает множество проблем при «обертывании» некоторого класса новой функциональностью, как вы пытаетесь это сделать.

9
ответ дан 18 December 2019 в 13:18
поделиться

once you have property with same name 'foo' it overrides the behaviour of access of name 'foo' only way out seems that you explicitly set 'foo' in dict

btw: I use python 2.5 hence had to change code a bit

class Base(object):
    def __init__(self):
        self.foo = 5

class Derived(Base):
    def __init__(self):
        Base.__init__(self)

    def g_foo(self):
        return 1 + self.__dict__['foo'] # works now!

    def s_foo(self, f):
        self.__dict__['foo'] = f
        self._foo = f

    foo = property(g_foo, s_foo)

bar = Base()
print bar.foo

foobar = Derived()
print foobar.foo
0
ответ дан 18 December 2019 в 13:18
поделиться
class Foo(object):
    def __new__(cls, *args, **kw):
        return object.__new__(cls, *args, **kw)

    def __init__(self):
        self.foo = 5

class Bar(Foo):
    def __new__(cls, *args, **kw):
        self = object.__new__(cls, *args, **kw)
        self.__foo = Foo.__new__(Foo)
        return self

    def __init__(self):
        Foo.__init__(self)

    @property
    def foo(self):
        return 1 + self.__foo.foo

    @foo.setter
    def foo(self, foo):
        self.__foo.foo = foo

bar = Bar()
bar.foo = 10
print bar.foo
1
ответ дан 18 December 2019 в 13:18
поделиться

Честно говоря, здесь стоит обратить внимание на то, что вы пытаетесь обернуть свой код вокруг просто плохого дизайна. Дескрипторы свойств обрабатывают запрос атрибута 'foo', и вы хотите полностью их обойти, что совершенно неправильно. Вы уже вызываете Base. init для назначения foobar._foo = 5, так что именно там и должен искать геттер.

class Base (object): def init (сам): self.foo = 5

class Derived(Base):
  def __init__(self):
    Base.__init__(self)

  @property
  def foo(self):
    return 1 + self._foo # DOES work of course!

  @foo.setter
  def foo(self, f):
    self._foo = f

bar = Base()
print bar.foo

foobar = Derived()
print foobar.foo
0
ответ дан 18 December 2019 в 13:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: