python只读模式可以打印嘛_只读python属性?无法打印对象
在Python中,使用自定義描述符可以很容易地做到這一點。在
看看HOWTO中的Descriptor Example。如果您只需更改__get__方法來引發一個AttributeError就這樣了。我們不妨將其重命名,去掉日志記錄,使之更簡單。在class WriteOnly(object):
"""A data descriptor that can't be read.
"""
def __init__(self, initval=None, name='var'):
self.val = initval
self.name = name
def __get__(self, obj, objtype):
raise AttributeError("No peeking at attribute '{}'!".format(self.name))
def __set__(self, obj, val):
self.val = val
class MyClass(object):
x = WriteOnly(0, 'x')
m = MyClass()
m.x = 20 # works
print(m.x) # raises AttributeError
請注意,在2.x中,如果您忘記了(object)并創建了一個經典類,描述符將無法工作。(我相信描述符本身可以是經典類…但不要這樣做。)在3.x中,沒有經典類,所以這不是問題。在
所以,如果這個值是只寫的,你會怎么讀呢?在
這個玩具例子沒用。但是,例如,您可以在obj上而不是在自己身上設置一些私有屬性,此時知道數據存儲在哪里的代碼可以找到它,但是偶然的自省就不能找到它
但你甚至不需要描述符。如果您希望屬性只寫而不管附加到哪個類,這是一回事,但是如果您只想阻止對特定類的某些成員的讀訪問,有一種更簡單的方法:
^{pr2}$
有關更多詳細信息,請參閱文檔中data model一章中的__getattr__和__getattribute__文檔。在
在2.x中,如果您不使用(object)并創建一個經典類,那么屬性查找的規則就完全不同了,而且沒有完全文檔化,除非您計劃在90年代花費大量時間,否則您確實不想學習這些規則,所以……不要這樣做。另外,2.x顯然需要2.x樣式的顯式super調用,而不是3.x風格的magicsuper()。在
從capi的角度來看,您已經擁有了大多數相同的鉤子,但是它們有點不同。有關詳細信息,請參見^{}s,但基本上:tp_getset允許您用getter和setter函數自動構建描述符,這與@property相似,但不完全相同。在
tp_descr_get和{}分別用于構建描述符。在
tp_getattro和tp_setattro與__getattr__和{}相似,只是它們被調用的規則稍有不同,當您知道沒有基類需要掛接屬性訪問時,通常會調用PyObject_GenericGetAttr,而不是委派給{}。在
不過,你為什么要那樣做?在
就我個人而言,我做了這樣的事情來了解更多關于Python數據模型和描述符的信息,但這并不是把它放在已發布的庫中的理由。在
我猜測,往往是因為有人試圖在Python上強制錯誤地基于面向對象的封裝(基于傳統的C++模型),或者更糟糕的是,試圖通過封裝來構建java風格的安全性(如果沒有安全類加載器和所有附帶的加載程序,它們就不起作用)。在
但也有可能有一些通用代碼通過內省來使用這些對象,而“欺騙”這些代碼可能在某種程度上是有用的,而試圖欺騙人類用戶卻不是這樣。例如,想象一下一個序列化庫嘗試pickle或JSON-ify或其他所有屬性。您可以很容易地編寫它忽略不可讀的屬性。(當然,您也可以很容易地做到,比如,忽略前綴為_的屬性…)
至于為什么cx_Oracle會這樣做……我從來沒看過,所以我不知道。在
總結
以上是生活随笔為你收集整理的python只读模式可以打印嘛_只读python属性?无法打印对象的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 服务器放行6in4协议,最简单的接入IP
- 下一篇: dynamo python修改多个参数_