网站建设小细节图片,北京装修公司报价,平面设计培训内容,百度免费官网入口在Python中#xff0c;使用自定义描述符可以很容易地做到这一点。在看看HOWTO中的Descriptor Example。如果您只需更改__get__方法来引发一个AttributeError就这样了。我们不妨将其重命名#xff0c;去掉日志记录#xff0c;使之更简单。在class WriteOnly(object):使用自定义描述符可以很容易地做到这一点。在看看HOWTO中的Descriptor Example。如果您只需更改__get__方法来引发一个AttributeError就这样了。我们不妨将其重命名去掉日志记录使之更简单。在class WriteOnly(object):A data descriptor that cant be read.def __init__(self, initvalNone, namevar):self.val initvalself.name namedef __get__(self, obj, objtype):raise AttributeError(No peeking at attribute {}!.format(self.name))def __set__(self, obj, val):self.val valclass MyClass(object):x WriteOnly(0, x)m MyClass()m.x 20 # worksprint(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会这样做……我从来没看过所以我不知道。在