[英]Python: dynamically add attributes to new-style class/obj
Can I dynamically add attributes to instances of a new-style class (one that derives from object
)? 我可以动态地向新类(从
object
派生的类)的实例添加属性吗?
Details: 细节:
I'm working with an instance of sqlite3.Connection. 我正在使用sqlite3.Connection的实例。 Simply extending the class isn't an option because I don't get the instance by calling a constructor;
简单地扩展类不是一个选择,因为我不能通过调用构造函数来获取实例; I get it by calling
sqlite3.connect()
. 我通过调用
sqlite3.connect()
获得它。
Building a wrapper doesn't save me much of the bulk for the code I'm writing. 构建包装器并不能为我编写的代码节省很多时间。
Python 2.7.1 Python 2.7.1
Edit 编辑
Right answers all. 正确回答所有。 But I still am not reaching my goal;
但是我仍然没有达到我的目标。 instances of sqlite3.Connection bar my attempts to set attributes in the following ways (as do instances of
object
itself). 我尝试通过以下方式设置sqlite3.Connection实例的属性(
object
本身的实例也是如此)。 I always get an AttributeError: 我总是得到AttributeError:
> conn = sqlite3.connect([filepath])
> conn.a = 'foo'
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
conn.a = 'foo'
AttributeError: 'object' object has no attribute 'a'
> conn.__setattr__('a','foo')
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
conn.__setattr__('a','foo')
AttributeError: 'object' object has no attribute 'a'
Help? 救命?
Yes, unless the class is using __slots__
or preventing attribute writing by overriding __setattr__
, or an internal Python class, or a Python class implemented natively (usually in C). 是的,除非该类使用
__slots__
或通过重写__setattr__
或内部Python类或本机实现的Python类(通常在C语言中)来防止属性写入。
You can always try setting an attribute. 您可以随时尝试设置属性。 Except for seriously weird
__setattr__
implementations, assigning an attribute to an instance of a class of one of the types mentioned above should raise an AttributeError
. 除了非常怪异的
__setattr__
实现之外,将属性分配给上述类型之一的类的实例应引发AttributeError
。 In these cases, you'll have to use a wrapper, like this: 在这些情况下,您将必须使用包装器,如下所示:
class AttrWrapper(object):
def __init__(self, wrapped):
self._wrapped = wrapped
def __getattr__(self, n):
return getattr(self._wrapped, n)
conn = AttrWrapper(sqlite3.connect(filepath))
Simple experimentation: 简单实验:
In []: class Tst(object): pass
..:
In []: t= Tst()
In []: t.attr= 'is this valid?'
In []: t.attr
Out[]: 'is this valid?'
So, indeed it seems to be possible to do that. 因此,确实似乎可以做到这一点。
Update: 更新:
But from the documentation: SQLite is a C library that ... , so it seems that you really need to wrap it. 但是从文档来看: SQLite是一个...的C库 ,因此看来您确实需要包装它。
conn.a = 'foo',
or any dynamic assignment is valid, if conn is 或任何动态分配有效,如果conn为
<type 'classobj'>.
Things like: 像:
c=object()
c.e=1
will raise an Attribute error. 将引发属性错误。 On the otherhand: Python allows you to do fantastic Metaclass programming:
另一方面:Python使您可以进行出色的元类编程:
>>>from new import classobj
>>>Foo2 = classobj('Foo2',(Foo,),{'bar':lambda self:'bar'})
>>>Foo2().bar()
>>>'bar'
>>>Foo2().say_foo()
>>>foo
The magic word here is "monkey patching". 这里的魔术词是“猴子修补”。 Here's an SO answer with examples.
这是一个带有示例的解答 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.