Обновление до последней версии Gradle решает мою проблему:
classpath 'com.android.tools.build:gradle:0.13.+'
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
.
Жизнь проще, если вы используете делегирование вместо наследования. Это 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 )
Да, это не похоже на «СУХОЙ». Однако это предотвращает множество проблем при «обертывании» некоторого класса новой функциональностью, как вы пытаетесь это сделать.
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
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
Честно говоря, здесь стоит обратить внимание на то, что вы пытаетесь обернуть свой код вокруг просто плохого дизайна. Дескрипторы свойств обрабатывают запрос атрибута '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