これは、次のような仮定を回避する方法です。
すべてのユーザーは成人に同意しているため、自分で物事を正しく使用する責任があります。
以下の私の更新を参照してください
の使用@property
は非常に冗長です。例:
class AClassWithManyAttributes:
'''refactored to properties'''
def __init__(a, b, c, d, e ...)
self._a = a
self._b = b
self._c = c
self.d = d
self.e = e
@property
def a(self):
return self._a
@property
def b(self):
return self._b
@property
def c(self):
return self._c
# you get this ... it's long
使用する
アンダースコアなし:これはパブリック変数です。
1つのアンダースコア:これは保護された変数です。
2つのアンダースコア:これはプライベート変数です。
最後のものを除いて、それは慣習です。それでも、本当に一生懸命努力すれば、二重アンダースコアで変数にアクセスできます。
どうしようか?Pythonで読み取り専用プロパティを使用することを諦めますか?
見よ!read_only_properties
デコレータが救助に!
@read_only_properties('readonly', 'forbidden')
class MyClass(object):
def __init__(self, a, b, c):
self.readonly = a
self.forbidden = b
self.ok = c
m = MyClass(1, 2, 3)
m.ok = 4
# we can re-assign a value to m.ok
# read only access to m.readonly is OK
print(m.ok, m.readonly)
print("This worked...")
# this will explode, and raise AttributeError
m.forbidden = 4
あなたが尋ねる:
どこread_only_properties
から来たの?
よろしくお願いします。read_only_propertiesのソースは次のとおりです。
def read_only_properties(*attrs):
def class_rebuilder(cls):
"The class decorator"
class NewClass(cls):
"This is the overwritten class"
def __setattr__(self, name, value):
if name not in attrs:
pass
elif name not in self.__dict__:
pass
else:
raise AttributeError("Can't modify {}".format(name))
super().__setattr__(name, value)
return NewClass
return class_rebuilder
アップデート
この答えがこれほど注目されるとは思ってもみませんでした。驚くべきことに、そうです。これにより、使用できるパッケージを作成するようになりました。
$ pip install read-only-properties
Pythonシェルで:
In [1]: from rop import read_only_properties
In [2]: @read_only_properties('a')
...: class Foo:
...: def __init__(self, a, b):
...: self.a = a
...: self.b = b
...:
In [3]: f=Foo('explodes', 'ok-to-overwrite')
In [4]: f.b = 5
In [5]: f.a = 'boom'
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-5-a5226072b3b4> in <module>()
----> 1 f.a = 'boom'
/home/oznt/.virtualenvs/tracker/lib/python3.5/site-packages/rop.py in __setattr__(self, name, value)
116 pass
117 else:
--> 118 raise AttributeError("Can't touch {}".format(name))
119
120 super().__setattr__(name, value)
AttributeError: Can't touch a