在 Python 中设置只读属性? [英] Set a Read-Only Attribute in Python?
问题描述
鉴于 Python 的动态性,如果这不可能实现,我会感到震惊:
Given how dynamic Python is, I'll be shocked if this isn't somehow possible:
我想改变sys.stdout.write
的实现.
我从这个对我的另一个问题的回答中得到了这个想法:https://stackoverflow.com/a/24492990/901641
I got the idea from this answer to another question of mine: https://stackoverflow.com/a/24492990/901641
我试着简单地写这个:
original_stdoutWrite = sys.stdout.write
def new_stdoutWrite(*a, **kw):
original_stdoutWrite("The new one was called! ")
original_stdoutWrite(*a, **kw)
sys.stdout.write = new_stdoutWrite
但它告诉我 AttributeError: 'file' 对象属性 'write' 是只读的
.
这是一个很好的尝试,可以防止我做一些可能(可能)愚蠢的事情,但我真的很想继续做下去.我怀疑解释器有某种我可以修改的查找表,但我在谷歌上找不到类似的东西.__setattr__
也不起作用 - 它返回了关于属性为只读的完全相同的错误.
This is a nice attempt to keep me from doing something potentially (probably) stupid, but I'd really like to go ahead and do it anyways. I suspect the interpreter has some kind of lookup table its using that I can modify, but I couldn't find anything like that on Google. __setattr__
didn't work, either - it returned the exact same error about the attribute being read-only.
我特别在寻找 Python 2.7 解决方案,如果这很重要,尽管没有理由拒绝提供适用于其他版本的答案,因为我怀疑将来其他人会在这里查看有关其他版本的类似问题.
I'm specifically looking for a Python 2.7 solution, if that's important, although there's no reason to resist throwing in answers that work for other versions since I suspect other people in the future will look here with similar questions regarding other versions.
推荐答案
尽管具有动态性,Python 不允许对诸如 file
之类的内置类型进行猴子修补.它甚至可以通过修改此类类型的 __dict__
来阻止您这样做 - __dict__
属性返回包装在只读代理中的 dict,因此都分配给 file.write
和 file.__dict__['write']
失败.并且至少有两个很好的理由:
Despite its dynamicity, Python does not allow monkey-patching built-in types such as file
. It even prevents you to do so by modifying the __dict__
of such a type — the __dict__
property returns the dict wrapped in a read-only proxy, so both assignment to file.write
and to file.__dict__['write']
fail. And for at least two good reasons:
C 代码期望
file
内置类型对应于PyFile
类型结构,而file.write
对应于内部使用的PyFile_Write()
函数.
the C code expects the
file
built-in type to correspond to thePyFile
type structure, andfile.write
to thePyFile_Write()
function used internally.
Python 实现了对类型的属性访问的缓存,以加快方法查找和实例方法的创建.如果允许直接分配给类型字典,此缓存将被破坏.
Python implements caching of attribute access on types to speed up method lookup and instance method creation. This cache would be broken if it were allowed to directly assign to type dicts.
对于用 Python 实现的类,当然可以使用 Monkey-patching,它可以很好地处理动态修改.
Monkey-patching is of course allowed for classes implemented in Python which can handle dynamic modifications just fine.
但是……如果您真的知道自己在做什么,则可以使用诸如 ctypes
之类的低级 API 来挂钩实现并获取类型 dict.例如:
However... if you really know what you are doing, you can use the low-level APIs such as ctypes
to hook into the implementation and get to the type dict. For example:
# WARNING: do NOT attempt this in production code!
import ctypes
def magic_get_dict(o):
# find address of dict whose offset is stored in the type
dict_addr = id(o) + type(o).__dictoffset__
# retrieve the dict object itself
dict_ptr = ctypes.cast(dict_addr, ctypes.POINTER(ctypes.py_object))
return dict_ptr.contents.value
def magic_flush_mro_cache():
ctypes.PyDLL(None).PyType_Modified(ctypes.py_object(object))
# monkey-patch file.write
dct = magic_get_dict(file)
dct['write'] = lambda f, s, orig_write=file.write: orig_write(f, '42')
# flush the method cache for the monkey-patch to take effect
magic_flush_mro_cache()
# magic!
import sys
sys.stdout.write('hello world\n')
这篇关于在 Python 中设置只读属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!