getter 및 setter의 광범위한 사용에서 속성의 비단뱀 사용으로 일부 클래스를 변경하고 있습니다.
하지만 이제는 이전 getter 또는 setter 중 일부가 기본 클래스의 해당 메서드를 호출 한 다음 다른 작업을 수행하기 때문에 문제가 발생합니다. 그러나 이것이 속성으로 어떻게 이루어질 수 있습니까? 부모 클래스에서 속성 getter 또는 setter를 호출하는 방법은 무엇입니까?
물론 속성 자체를 호출하는 것만으로도 무한 재귀를 얻을 수 있습니다.
class Foo(object):
@property
def bar(self):
return 5
@bar.setter
def bar(self, a):
print a
class FooBar(Foo):
@property
def bar(self):
# return the same value
# as in the base class
return self.bar # --> recursion!
@bar.setter
def bar(self, c):
# perform the same action
# as in the base class
self.bar = c # --> recursion!
# then do something else
print 'something else'
fb = FooBar()
fb.bar = 7
답변
속성에 의해 호출되는 기본 클래스 함수를 호출 할 수 있다고 생각할 수 있습니다.
class FooBar(Foo):
@property
def bar(self):
# return the same value
# as in the base class
return Foo.bar(self)
이것이 시도해 볼 수있는 가장 명백한 것임에도 불구하고 , bar는 콜 러블이 아니라 속성이기 때문에 작동하지 않습니다.
그러나 속성은 해당 속성을 찾는 getter 메서드가있는 개체 일뿐입니다.
class FooBar(Foo):
@property
def bar(self):
# return the same value
# as in the base class
return Foo.bar.fget(self)
답변
Super 가 트릭을해야합니다.
return super().bar
Python 2.x에서는보다 자세한 구문을 사용해야합니다.
return super(FooBar, self).bar
답변
사용하는 대안이 있습니다 super
기본 클래스 이름을 명시 적으로 참조 할 필요가없는 이 있습니다.
기본 등급 A :
class A(object):
def __init__(self):
self._prop = None
@property
def prop(self):
return self._prop
@prop.setter
def prop(self, value):
self._prop = value
class B(A):
# we want to extend prop here
pass
B에서 부모 클래스 A의 속성 getter에 액세스 :
다른 사람들이 이미 대답했듯이 다음과 같습니다.
super(B, self).prop
또는 Python 3에서 :
super().prop
이것은 getter 자체가 아니라 속성의 getter가 반환 한 값을 반환하지만 getter를 확장하는 것으로 충분합니다.
B에서 부모 클래스 A의 속성 setter에 액세스 :
지금까지 본 최고의 권장 사항은 다음과 같습니다.
A.prop.fset(self, value)
나는 이것이 더 낫다고 믿는다.
super(B, self.__class__).prop.fset(self, value)
이 예에서 두 옵션은 모두 동일하지만 super를 사용하면의 기본 클래스와 독립적이라는 이점이 B
있습니다. 속성을 확장 B
하는 C
클래스 에서 상속하는 경우 B
의 코드 를 업데이트 할 필요가 없습니다 .
A의 속성을 확장하는 B의 전체 코드 :
class B(A):
@property
def prop(self):
value = super(B, self).prop
# do something with / modify value here
return value
@prop.setter
def prop(self, value):
# do something with / modify value here
super(B, self.__class__).prop.fset(self, value)
한 가지주의 사항 :
속성에 setter가 없으면 둘 B
중 하나의 동작 만 변경하더라도 setter와 getter를 모두 정의 해야합니다.
답변
시험
@property
def bar:
return super(FooBar, self).bar
파이썬이 기본 클래스 속성 호출을 지원하는지 확실하지 않지만. 속성은 실제로 지정된 함수로 설정된 다음 클래스에서 해당 이름을 대체하는 호출 가능한 객체입니다. 이것은 사용 가능한 슈퍼 기능이 없음을 쉽게 의미 할 수 있습니다.
그래도 항상 property () 함수를 사용하도록 구문을 전환 할 수 있습니다.
class Foo(object):
def _getbar(self):
return 5
def _setbar(self, a):
print a
bar = property(_getbar, _setbar)
class FooBar(Foo):
def _getbar(self):
# return the same value
# as in the base class
return super(FooBar, self)._getbar()
def bar(self, c):
super(FooBar, self)._setbar(c)
print "Something else"
bar = property(_getbar, _setbar)
fb = FooBar()
fb.bar = 7
답변
Maxime의 답변에 대한 몇 가지 작은 개선 사항 :
__class__
쓰기를 피하기 위해 사용B
. 주self.__class__
의 실행시의 형태이다self
,하지만__class__
하지 않고는self
바깥 쪽 클래스 정의의 이름입니다.super()
는super(__class__, self)
.- 사용
__set__
대신에fset
. 후자는property
s에만 해당되지만 전자는 모든 속성 유사 객체 (설명자)에 적용됩니다.
class B(A):
@property
def prop(self):
value = super().prop
# do something with / modify value here
return value
@prop.setter
def prop(self, value):
# do something with / modify value here
super(__class__, self.__class__).prop.__set__(self, value)
답변
다음 템플릿을 사용할 수 있습니다.
class Parent():
def __init__(self, value):
self.__prop1 = value
#getter
@property
def prop1(self):
return self.__prop1
#setter
@prop1.setter
def prop1(self, value):
self.__prop1 = value
#deleter
@prop1.deleter
def prop1(self):
del self.__prop1
class Child(Parent):
#getter
@property
def prop1(self):
return super(Child, Child).prop1.__get__(self)
#setter
@prop1.setter
def prop1(self, value):
super(Child, Child).prop1.__set__(self, value)
#deleter
@prop1.deleter
def prop1(self):
super(Child, Child).prop1.__delete__(self)
노트! 모든 속성 메서드를 함께 다시 정의해야합니다. 모든 방법을 재정의하지 않으려면 대신 다음 템플릿을 사용하십시오.
class Parent():
def __init__(self, value):
self.__prop1 = value
#getter
@property
def prop1(self):
return self.__prop1
#setter
@prop1.setter
def prop1(self, value):
self.__prop1 = value
#deleter
@prop1.deleter
def prop1(self):
del self.__prop1
class Child(Parent):
#getter
@Parent.prop1.getter
def prop1(self):
return super(Child, Child).prop1.__get__(self)
#setter
@Parent.prop1.setter
def prop1(self, value):
super(Child, Child).prop1.__set__(self, value)
#deleter
@Parent.prop1.deleter
def prop1(self):
super(Child, Child).prop1.__delete__(self)
답변
class Base(object):
def method(self):
print "Base method was called"
class Derived(Base):
def method(self):
super(Derived,self).method()
print "Derived method was called"
d = Derived()
d.method()
(당신의 설명에서 빠진 것이 없다면)