문제

서브 클래스로 덮어 쓰고 싶은 속성이있는 기본 클래스가 있습니다. 내 첫 생각은 다음과 같습니다.

class Foo(object):
    def _get_age(self):
        return 11

    age = property(_get_age)


class Bar(Foo):
    def _get_age(self):
        return 44

이것은 작동하지 않습니다 (서브 클래스 바 .age 11). 나는 Lambda 표현이있는 솔루션을 찾았습니다.

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) Python 2.6에서 속성은 한 쌍의 방법으로 성장했습니다 setter 그리고 deleter 일반 속성에 적용하는 데 사용할 수 있습니다. 이미 읽기 전용으로 사용 가능한 바로 가기입니다.

class C(object):
    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, value):
        self._x = value

다른 팁

선택한 답변이 속성 방법을 무시할 수있는 이상적인 방법이라는 데 동의하지 않습니다. Getters와 Setter가 무시 될 것으로 예상되면 Lambda를 사용하여 자신에게 접근 할 수 있습니다. lambda self: self.<property func>.

이것은 Python 버전 2.4 ~ 3.6의 경우 (적어도) 작동합니다.

직접 속성 () 호출 대신 데코레이터로 속성을 사용 하여이 작업을 수행하는 방법을 알고 있다면 듣고 싶습니다.

예시:

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"

나는 이것을 발견했다 놀이 치는 괴짜.

추가 수업을 만들 필요없이이를 수행하는 또 다른 방법. 두 가지 중 하나만 재정의 경우 귀하가 수행하는 작업을 보여주는 세트 메소드를 추가했습니다.

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

동일 @MR-B그러나 데코레이터와 함께.

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)

이런 식으로 재정의를 쉽게 수행 할 수 있습니다.

class Bar(Foo):
    def _get_meow(self):
        return super(Bar, self)._get_meow() + ', altered by a Bar'

나는 아동 수업에서 부모 수업에서 재산을 설정하는 데 문제가있었습니다. 다음 워크 라운드는 부모의 속성을 확장하지만 부모의 _set_age 메소드를 직접 호출하여 그렇게합니다. 주름진은 항상 정확해야합니다. 그래도 조금 javathonic입니다.

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)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top