するのが、最も簡潔な方法を選択した属性のインスタンスすると読み取り専用?

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

  •  02-07-2019
  •  | 
  •  

質問

Pythonでは、作りたい 選択 インスタンス属性のプログラミング未経験者を読み取り専用のコード以外のクラスです。でありたいと思いますできない社外コードを変更することが可能な属性を除き、間接的にメソッドを呼び出方法のインスタンス.してほしい構文を簡潔でなければならない。には、どうするのがベストなの?(以下の通りで現在最高の答えット-イット-ラウダー)

役に立ちましたか?

解決

をお使いください @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.読み取り専用=22
変更することができません。読み取り専用
c.読み取り専用=22
c.読み取り専用=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)

を想定 foobarblahblah の属性たい読み取り専用になります。) Prepending 二つの 字属性名を効果的に隠すので外部からのクラスであり、内部バージョンさんからアクセス可能です。この だけ新しい形式のクラスを継承からオブジェクト より異なりますので property.

一方...このかわいらしい愚かしいことだと思います。を変数の民間のようだがわからこその、C++およびJava.ユーザーの公共インターフェースのクラスでもない力しています。

編集:のように見えKevinて掲載して同様のバージョン。

がないのが現実ではないかと思います。そこでより難しくもありません概念を完全に隠し、利用できなクラス属性にまで広げられます。

者の場合、ご利用のクラスでも会社のAPIドキュメント、それはそれ自身の問題です。から守って愚かなんだからいかに精巧な複雑な、愚かなものにしてみんなが行っています。

を使用してくださ形式のメタクラスがオートラップ方法(またはクラスの属性に従うネーミング大会への特性(shamelesslyから 統一種およびクラスをPython2.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