python只读模式可以打印嘛_只读python属性?无法打印对象
在Python中,使用自定義描述符可以很容易地做到這一點。在
看看HOWTO中的Descriptor Example。如果您只需更改__get__方法來引發(fā)一個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)并創(chuàng)建了一個經(jīng)典類,描述符將無法工作。(我相信描述符本身可以是經(jīng)典類…但不要這樣做。)在3.x中,沒有經(jīng)典類,所以這不是問題。在
所以,如果這個值是只寫的,你會怎么讀呢?在
這個玩具例子沒用。但是,例如,您可以在obj上而不是在自己身上設(shè)置一些私有屬性,此時知道數(shù)據(jù)存儲在哪里的代碼可以找到它,但是偶然的自省就不能找到它
但你甚至不需要描述符。如果您希望屬性只寫而不管附加到哪個類,這是一回事,但是如果您只想阻止對特定類的某些成員的讀訪問,有一種更簡單的方法:
^{pr2}$
有關(guān)更多詳細信息,請參閱文檔中data model一章中的__getattr__和__getattribute__文檔。在
在2.x中,如果您不使用(object)并創(chuàng)建一個經(jīng)典類,那么屬性查找的規(guī)則就完全不同了,而且沒有完全文檔化,除非您計劃在90年代花費大量時間,否則您確實不想學(xué)習(xí)這些規(guī)則,所以……不要這樣做。另外,2.x顯然需要2.x樣式的顯式super調(diào)用,而不是3.x風(fēng)格的magicsuper()。在
從capi的角度來看,您已經(jīng)擁有了大多數(shù)相同的鉤子,但是它們有點不同。有關(guān)詳細信息,請參見^{}s,但基本上:tp_getset允許您用getter和setter函數(shù)自動構(gòu)建描述符,這與@property相似,但不完全相同。在
tp_descr_get和{}分別用于構(gòu)建描述符。在
tp_getattro和tp_setattro與__getattr__和{}相似,只是它們被調(diào)用的規(guī)則稍有不同,當您知道沒有基類需要掛接屬性訪問時,通常會調(diào)用PyObject_GenericGetAttr,而不是委派給{}。在
不過,你為什么要那樣做?在
就我個人而言,我做了這樣的事情來了解更多關(guān)于Python數(shù)據(jù)模型和描述符的信息,但這并不是把它放在已發(fā)布的庫中的理由。在
我猜測,往往是因為有人試圖在Python上強制錯誤地基于面向?qū)ο蟮姆庋b(基于傳統(tǒng)的C++模型),或者更糟糕的是,試圖通過封裝來構(gòu)建java風(fēng)格的安全性(如果沒有安全類加載器和所有附帶的加載程序,它們就不起作用)。在
但也有可能有一些通用代碼通過內(nèi)省來使用這些對象,而“欺騙”這些代碼可能在某種程度上是有用的,而試圖欺騙人類用戶卻不是這樣。例如,想象一下一個序列化庫嘗試pickle或JSON-ify或其他所有屬性。您可以很容易地編寫它忽略不可讀的屬性。(當然,您也可以很容易地做到,比如,忽略前綴為_的屬性…)
至于為什么cx_Oracle會這樣做……我從來沒看過,所以我不知道。在
總結(jié)
以上是生活随笔為你收集整理的python只读模式可以打印嘛_只读python属性?无法打印对象的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 服务器放行6in4协议,最简单的接入IP
- 下一篇: mysql导入数据提前修改字段_复习My