어떤 가장 쉽고 간결한 방법을 선택한 속성 인스턴스에서 수 readonly?

StackOverflow https://stackoverflow.com/questions/125034

  •  02-07-2019
  •  | 
  •  

문제

파이썬에서,만들고 싶 선택 인스턴스의 속성 클래스를 읽기 전용 코드의 외부 클래스입니다.고 싶을 수 있는 방법이 없 외부 코드 변경할 수 있는 특성을 제외하고,에 의해 간접적으로 호출하는 방법에는 인스턴스입니다.내가 원하는 구문을 간결하고 있습니다.최고의 방법은 무엇인가?(I give my 현재 최고의 답변이 아래...)

도움이 되었습니까?

해결책

당신은 사용해야합니다 @property 데코레이터.

>>> class a(object):
...     def __init__(self, x):
...             self.x = x
...     @property
...     def xval(self):
...             return self.x
... 
>>> b = a(5)
>>> b.xval
5
>>> b.xval = 6
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

다른 팁

class C(object):

    def __init__(self):

        self.fullaccess = 0
        self.__readonly = 22 # almost invisible to outside code...

    # define a publicly visible, read-only version of '__readonly':
    readonly = property(lambda self: self.__readonly)

    def inc_readonly( self ):
        self.__readonly += 1

c=C()

# prove regular attribute is RW...
print "c.fullaccess = %s" % c.fullaccess
c.fullaccess = 1234
print "c.fullaccess = %s" % c.fullaccess

# prove 'readonly' is a read-only attribute
print "c.readonly = %s" % c.readonly
try:
    c.readonly = 3
except AttributeError:
    print "Can't change c.readonly"
print "c.readonly = %s" % c.readonly

# change 'readonly' indirectly...
c.inc_readonly()
print "c.readonly = %s" % c.readonly

이 출력 :

$ python ./p.py
c.fullaccess = 0
c.fullaccess = 1234
c.readonly = 22
c.readonly를 변경할 수 없습니다
c.readonly = 22
c.readonly = 23

내 손가락은 가려움증을 말할 수있게한다

    @readonly
    self.readonly = 22

즉, 속성에 데코레이터를 사용하십시오. 너무 깨끗 할 것입니다 ...

방법은 다음과 같습니다.

class whatever(object):
  def __init__(self, a, b, c, ...):
    self.__foobar = 1
    self.__blahblah = 2

  foobar = property(lambda self: self.__foobar)
  blahblah = property(lambda self: self.__blahblah)

(가정 foobar 그리고 blahblah 읽기 전용이되고 싶은 속성입니다.) 선불 속성 이름을 강조하면 클래스 외부에서 효과적으로 숨겨져 있으므로 내부 버전은 외부에서 액세스 할 수 없습니다. 이것 객체에서 상속되는 새 스타일 클래스에만 작동합니다 그것은 의존하기 때문에 property.

반면에 ... 이것은 꽤 어리석은 일입니다. 변수를 비공개로 유지하는 것은 C ++와 Java에서 나오는 강박 관념 인 것 같습니다. 사용자는 공개 인터페이스를 클래스에 사용해야합니다.

편집 : Kevin이 이미 비슷한 버전을 게시 한 것 같습니다.

이것을 할 수있는 진정한 방법은 없습니다. 더 어려운 방법이 있지만 완전히 숨겨져 있고 접근 할 수없는 클래스 속성의 개념은 없습니다.

수업을 사용하는 사람이 API 문서를 따르기로 신뢰할 수 없다면, 이것이 자신의 문제입니다. 사람들이 어리석은 일을하지 않도록 보호한다는 것은 그들이 처음에는하지 않았던 모든 일을하기 위해 훨씬 더 정교하고 복잡하며 어리석은 일을 해칠 것임을 의미합니다.

이름 지정 규칙을 따르는 자동 랩 방법 (또는 클래스 속성)이 속성 (뻔뻔스럽게 채취 한)을 사용할 수 있습니다. Python 2.2의 통일 유형 및 클래스:

class autoprop(type):
    def __init__(cls, name, bases, dict):
        super(autoprop, cls).__init__(name, bases, dict)
        props = {}
        for name in dict.keys():
            if name.startswith("_get_") or name.startswith("_set_"):
                props[name[5:]] = 1
        for name in props.keys():
            fget = getattr(cls, "_get_%s" % name, None)
            fset = getattr(cls, "_set_%s" % name, None)
            setattr(cls, name, property(fget, fset))

이를 통해 사용할 수 있습니다.

class A:
    __metaclass__ = autosuprop
    def _readonly(self):
        return __x

내가 알고 있는 윌리엄 켈러는 가장 깨끗한 솔루션입니다.그러나 여기에서 내가 왔다.

class readonly(object):
    def __init__(self, attribute_name):
        self.attribute_name = attribute_name

    def __get__(self, instance, instance_type):
        if instance != None:
            return getattr(instance, self.attribute_name)
        else:
            raise AttributeError("class %s has no attribute %s" % 
                                 (instance_type.__name__, self.attribute_name))

    def __set__(self, instance, value):
        raise AttributeError("attribute %s is readonly" % 
                              self.attribute_name)

그리고 여기에 사용 예

class a(object):
    def __init__(self, x):
        self.x = x
    xval = readonly("x")

불행하게도 이 솔루션을 처리할 수 없습니다 개인 변수(__라는 변수).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top