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会这样做……我从来没看过,所以我不知道。在

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值