파이썬 속성과 상속
하위 클래스에서 덮어 쓰려는 속성 (get 메서드)이있는 기본 클래스가 있습니다. 내 첫 생각은 다음과 같았습니다.
class Foo(object):
def _get_age(self):
return 11
age = property(_get_age)
class Bar(Foo):
def _get_age(self):
return 44
이것은 작동하지 않습니다 (하위 클래스 bar.age가 11을 리턴 함). 작동하는 람다 식으로 솔루션을 찾았습니다.
age = property(lambda self: self._get_age())
그렇다면 이것이 속성을 사용하고 하위 클래스에서 덮어 쓰기에 적합한 솔루션입니까, 아니면 다른 선호하는 방법이 있습니까?
클래스 메서드를 재정의 할 때 데코레이터 property()
를 반복 할뿐만 아니라 반복하는 것을 선호합니다 @classmethod
.
이것은 매우 장황 해 보이지만 적어도 Python 표준에서는 다음과 같은 것을 알 수 있습니다.
1) 읽기 전용 속성의 property
경우 데코레이터로 사용할 수 있습니다.
class Foo(object):
@property
def age(self):
return 11
class Bar(Foo):
@property
def age(self):
return 44
2) 파이썬 2.6, 속성은 방법의 한 쌍의 성장 setter
하고 deleter
있는 일반적인 속성에 읽기 전용 사람을위한 이미 사용할 수있는 바로 가기를 적용 할 수 있습니다 :
class C(object):
@property
def x(self):
return self._x
@x.setter
def x(self, value):
self._x = value
선택한 답변이 속성 메서드를 재정의 할 수있는 이상적인 방법이라는 데 동의하지 않습니다. getter 및 setter가 재정의 될 것으로 예상하는 경우 람다를 사용하여 lambda self: self.<property func>
.
이것은 Python 버전 2.4 ~ 3.6에서 (적어도) 작동합니다.
직접 property () 호출 대신에 속성을 데코레이터로 사용하여이 작업을 수행하는 방법을 아는 사람이 있다면 듣고 싶습니다!
예:
class Foo(object):
def _get_meow(self):
return self._meow + ' from a Foo'
def _set_meow(self, value):
self._meow = value
meow = property(fget=lambda self: self._get_meow(),
fset=lambda self, value: self._set_meow(value))
이렇게하면 재정의를 쉽게 수행 할 수 있습니다.
class Bar(Foo):
def _get_meow(self):
return super(Bar, self)._get_meow() + ', altered by a Bar'
그래서:
>>> foo = Foo()
>>> bar = Bar()
>>> foo.meow, bar.meow = "meow", "meow"
>>> foo.meow
"meow from a Foo"
>>> bar.meow
"meow from a Foo, altered by a Bar"
추가 클래스를 만들지 않고이를 수행하는 또 다른 방법입니다. 두 가지 중 하나만 재정의하는 경우 수행 할 작업을 보여주는 set 메서드를 추가했습니다.
class Foo(object):
def _get_age(self):
return 11
def _set_age(self, age):
self._age = age
age = property(_get_age, _set_age)
class Bar(Foo):
def _get_age(self):
return 44
age = property(_get_age, Foo._set_age)
이것은 꽤 인위적인 예이지만 아이디어를 얻어야합니다.
예, 이것이 그렇게하는 방법입니다. 속성 선언은 부모 클래스의 정의가 실행될 때 실행됩니다. 즉, 부모 클래스에 존재하는 메서드의 버전 만 "볼"수 있습니다. 따라서 자식 클래스에서 이러한 메서드 중 하나 이상을 재정의 할 때 메서드의 자식 클래스 버전을 사용하여 속성을 다시 선언해야합니다.
즉시 템플릿 방식으로 보이는 귀하의 솔루션에 동의합니다. 이 기사 는 문제를 다루고 정확하게 해결책을 제공합니다.
이런 식으로 작동합니다.
class HackedProperty(object):
def __init__(self, f):
self.f = f
def __get__(self, inst, owner):
return getattr(inst, self.f.__name__)()
class Foo(object):
def _get_age(self):
return 11
age = HackedProperty(_get_age)
class Bar(Foo):
def _get_age(self):
return 44
print Bar().age
print Foo().age
Same as @mr-b's but with decorator.
class Foo(object):
def _get_meow(self):
return self._meow + ' from a Foo'
def _set_meow(self, value):
self._meow = value
@property
def meow(self):
return self._get_meow()
@meow.setter
def meow(self, value):
self._set_meow(value)
This way, an override can be easily performed:
class Bar(Foo):
def _get_meow(self):
return super(Bar, self)._get_meow() + ', altered by a Bar'
I ran into problems setting a property in a parent class from a child class. The following workround extends a property of a parent but does so by calling the _set_age method of the parent directly. Wrinkled should always be correct. It is a little javathonic though.
import threading
class Foo(object):
def __init__(self):
self._age = 0
def _get_age(self):
return self._age
def _set_age(self, age):
self._age = age
age = property(_get_age, _set_age)
class ThreadsafeFoo(Foo):
def __init__(self):
super(ThreadsafeFoo, self).__init__()
self.__lock = threading.Lock()
self.wrinkled = False
def _get_age(self):
with self.__lock:
return super(ThreadsafeFoo, self).age
def _set_age(self, value):
with self.__lock:
self.wrinkled = True if value > 40 else False
super(ThreadsafeFoo, self)._set_age(value)
age = property(_get_age, _set_age)
class Foo:
# Template method
@property
def age(self):
return self.dothis()
# Hook method of TM is accessor method of property at here
def dothis(self):
return 11
class Bar(Foo):
def dothis(self):
return 44
Same as Nizam Mohamed, just to mention that style guide 2.13.4 using both template method and property
ReferenceURL : https://stackoverflow.com/questions/237432/python-properties-and-inheritance
'IT박스' 카테고리의 다른 글
jQuery 또는 다른 라이브러리를 사용하는 Apple Cover-flow 효과? (0) | 2020.12.24 |
---|---|
asp : TextBox ReadOnly = true 또는 Enabled = false? (0) | 2020.12.24 |
C #의 측정 단위-거의 (0) | 2020.12.24 |
@ font-face 글꼴은 자체 도메인에서만 작동합니다. (0) | 2020.12.24 |
Paypal IPN은 항상 샌드 박스에서 "payment_status : Pending"을 반환합니까? (0) | 2020.12.24 |