import sys
_target_object = sys.stderr
_target_object_class_type = type( _target_object )
class TargetCopiedObject(_target_object_class_type):
"""
Which special methods bypasses __getattribute__ in Python?
https://stackoverflow.com/questions/12872695/which-special-methods-bypasses
"""
if hasattr( _target_object, "__abstractmethods__" ):
__abstractmethods__ = _target_object.__abstractmethods__
if hasattr( _target_object, "__base__" ):
__base__ = _target_object.__base__
if hasattr( _target_object, "__bases__" ):
__bases__ = _target_object.__bases__
if hasattr( _target_object, "__basicsize__" ):
__basicsize__ = _target_object.__basicsize__
if hasattr( _target_object, "__call__" ):
__call__ = _target_object.__call__
if hasattr( _target_object, "__class__" ):
__class__ = _target_object.__class__
if hasattr( _target_object, "__delattr__" ):
__delattr__ = _target_object.__delattr__
if hasattr( _target_object, "__dict__" ):
__dict__ = _target_object.__dict__
if hasattr( _target_object, "__dictoffset__" ):
__dictoffset__ = _target_object.__dictoffset__
if hasattr( _target_object, "__dir__" ):
__dir__ = _target_object.__dir__
if hasattr( _target_object, "__doc__" ):
__doc__ = _target_object.__doc__
if hasattr( _target_object, "__eq__" ):
__eq__ = _target_object.__eq__
if hasattr( _target_object, "__flags__" ):
__flags__ = _target_object.__flags__
if hasattr( _target_object, "__format__" ):
__format__ = _target_object.__format__
if hasattr( _target_object, "__ge__" ):
__ge__ = _target_object.__ge__
if hasattr( _target_object, "__getattribute__" ):
__getattribute__ = _target_object.__getattribute__
if hasattr( _target_object, "__gt__" ):
__gt__ = _target_object.__gt__
if hasattr( _target_object, "__hash__" ):
__hash__ = _target_object.__hash__
if hasattr( _target_object, "__init__" ):
__init__ = _target_object.__init__
if hasattr( _target_object, "__init_subclass__" ):
__init_subclass__ = _target_object.__init_subclass__
if hasattr( _target_object, "__instancecheck__" ):
__instancecheck__ = _target_object.__instancecheck__
if hasattr( _target_object, "__itemsize__" ):
__itemsize__ = _target_object.__itemsize__
if hasattr( _target_object, "__le__" ):
__le__ = _target_object.__le__
if hasattr( _target_object, "__lt__" ):
__lt__ = _target_object.__lt__
if hasattr( _target_object, "__module__" ):
__module__ = _target_object.__module__
if hasattr( _target_object, "__mro__" ):
__mro__ = _target_object.__mro__
if hasattr( _target_object, "__name__" ):
__name__ = _target_object.__name__
if hasattr( _target_object, "__ne__" ):
__ne__ = _target_object.__ne__
if hasattr( _target_object, "__new__" ):
__new__ = _target_object.__new__
if hasattr( _target_object, "__prepare__" ):
__prepare__ = _target_object.__prepare__
if hasattr( _target_object, "__qualname__" ):
__qualname__ = _target_object.__qualname__
if hasattr( _target_object, "__reduce__" ):
__reduce__ = _target_object.__reduce__
if hasattr( _target_object, "__reduce_ex__" ):
__reduce_ex__ = _target_object.__reduce_ex__
if hasattr( _target_object, "__repr__" ):
__repr__ = _target_object.__repr__
if hasattr( _target_object, "__setattr__" ):
__setattr__ = _target_object.__setattr__
if hasattr( _target_object, "__sizeof__" ):
__sizeof__ = _target_object.__sizeof__
if hasattr( _target_object, "__str__" ):
__str__ = _target_object.__str__
if hasattr( _target_object, "__subclasscheck__" ):
__subclasscheck__ = _target_object.__subclasscheck__
if hasattr( _target_object, "__subclasses__" ):
__subclasses__ = _target_object.__subclasses__
if hasattr( _target_object, "__subclasshook__" ):
__subclasshook__ = _target_object.__subclasshook__
if hasattr( _target_object, "__text_signature__" ):
__text_signature__ = _target_object.__text_signature__
if hasattr( _target_object, "__weakrefoffset__" ):
__weakrefoffset__ = _target_object.__weakrefoffset__
if hasattr( _target_object, "mro" ):
mro = _target_object.mro
# Copy all the other read only attributes
if hasattr( _target_object, "buffer" ):
buffer = _target_object.buffer
if hasattr( _target_object, "closed" ):
closed = _target_object.closed
if hasattr( _target_object, "encoding" ):
encoding = _target_object.encoding
if hasattr( _target_object, "errors" ):
errors = _target_object.errors
if hasattr( _target_object, "line_buffering" ):
line_buffering = _target_object.line_buffering
if hasattr( _target_object, "name" ):
name = _target_object.name
if hasattr( _target_object, "newlines" ):
newlines = _target_object.newlines
def __init__(self):
"""
Override any super class `type( _target_object )` constructor,
so we can instantiate any kind of replacement object.
Assures all properties were statically replaced just above. This
should happen in case some new attribute is added to the python
language.
This also ignores the only two methods which are not equal,
`__init__()` and `__getattribute__()`.
How do you programmatically set an attribute?
https://stackoverflow.com/questions/285061/how-do-you-programmatically
"""
# Add the copied read only atribute to the ignored list, so they
# do not throw new errors while trying copy they dynamically
different_methods = set\
([
"__init__",
"__getattribute__",
"buffer",
"closed",
"encoding",
"errors",
"line_buffering",
"name",
"newlines",
])
attributes_to_check = set( dir( object ) + dir( type ) )
attributes_to_copy = dir( _target_object )
# Check for missing magic built-ins methods on the class static initialization
for attribute in attributes_to_check:
if attribute not in different_methods \
and hasattr( _target_object, attribute ):
base_class_attribute = self.__getattribute__( attribute )
target_class_attribute = _target_object.__getattribute__( attribute )
if base_class_attribute != target_class_attribute:
sys.stdout.write(
" The base class attribute `%s` is different from the "
"target class:\n%s\n%s\n\n" % ( attribute,
base_class_attribute,
target_class_attribute ) )
# Finally copy everything it can
different_methods.update( attributes_to_check )
for attribute in attributes_to_copy:
if attribute not in different_methods:
print( "Setting:", attribute )
try:
target_class_attribute = _target_object.__getattribute__(attribute)
setattr( self, attribute, target_class_attribute )
except AttributeError as error:
print( "Error coping the attribute `%s`: %s" % (attribute, error) )
o = TargetCopiedObject()
print( "TargetCopiedObject:", o )
6条答案
按热度按时间lyr7nygr1#
试试
destination.__dict__.update(source.__dict__)
。7rtdyuoh2#
如果类没有修改
__getitem__
或__setitem__
以进行特殊属性访问,则所有属性都存储在__dict__
中,因此可以执行以下操作:如果你使用python属性,你应该查看
inspect.getmembers()
并过滤掉那些你想要复制的。enxuqcxy3#
如果您必须这样做,我想最好的方法是使用class属性,如下所示:
然后显式地迭代它们并使用
setattr(new, attr, getattr(old, attr))
。我仍然相信可以用更好的设计来解决这个问题,但不推荐它。7kqas0il4#
使用此选项,几乎可以将所有内容从一个对象复制到另一个对象:
但是,如果运行上面的代码,您将看到以下错误:
你只能在类静态初始化时复制这些只读属性,就像上面的其他内置magic python方法
__str__
一样:现在这个新版本完全可以应付一切:
它的缺点是你需要手工编写Python代码来克服只读属性,然而,你可以使用元编程动态地编写Python代码:
所以,如果你仔细研究了上面的初始代码,你就可以编写一个脚本来生成它所需要的代码,因此,你可以动态地、完整地复制任何Python对象。
enyaitl35#
冒着被修改的风险,有一个体面的任何用例吗?
除非我们确切地知道它的用途,否则我们不能明智地称之为“坏了”。
或许可以试试这个:
这是在示例之间复制事物的明智方式。
tvmytwxo6#
对于类对象,我发现最好添加它们自己的
copy
方法,这样可以解决deepcopy中内部的、不可pickelable的对象:在您的工作代码中,它将变为:
当然,这是一个小问题。实际上,如果类中有复杂的对象,而这些对象不能直接用
copy.deepcopy()
类型操作复制,你就可以这样做。如果这是一个简单的问题,只需使用b = copy.deepcopy(a)
,而不在类中显式定义即可。