นี่คือวิธีหลีกเลี่ยงข้อสันนิษฐานที่ว่า
ผู้ใช้ทุกคนยินยอมผู้ใหญ่ดังนั้นจึงต้องรับผิดชอบในการใช้สิ่งต่างๆอย่างถูกต้องด้วยตนเอง
โปรดดูการอัปเดตของฉันด้านล่าง
การใช้@property
เป็น verbose มากเช่น:
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
การใช้
ไม่มีขีดล่าง: เป็นตัวแปรสาธารณะ
ขีดล่างอันเดียว: เป็นตัวแปรที่มีการป้องกัน
ขีดล่างสองอัน: เป็นตัวแปรส่วนตัว
ยกเว้นข้อสุดท้ายมันเป็นอนุสัญญา คุณยังสามารถเข้าถึงตัวแปรด้วยขีดล่างคู่ได้หากคุณพยายามอย่างเต็มที่
ดังนั้นสิ่งที่เราจะทำ? เรายอมแพ้ที่จะมีคุณสมบัติอ่านอย่างเดียวใน 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
print(m.ok, m.readonly)
print("This worked...")
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 shell ของคุณ:
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
self.x
x
หากแน่ใจว่าx
ไม่สามารถเปลี่ยนแปลงได้เป็นสิ่งสำคัญให้ใช้คุณสมบัติ