我可以动态地将属性添加到新式类的实例(一个派生自object
的实例)吗?
详细说明:
我正在使用sqlite3.Connection的一个实例。简单地扩展类不是一个选项,因为我没有通过调用构造函数来获取实例;我通过致电sqlite3.connect()
来获得它。
构建一个包装器并没有为我正在编写的代码节省大量的工作量。
Python 2.7.1
修改
正确回答所有问题。但我仍然没有达到我的目标; sqlite3.Connection栏的实例我尝试以下列方式设置属性(就像object
本身的实例一样)。我总是得到一个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'
帮助?
答案 0 :(得分:5)
是的,除非该类使用__slots__
或通过覆盖__setattr__
或内部Python类或本机实现的Python类(通常在C中)来阻止属性编写。
您始终可以尝试设置属性。除了非常奇怪的__setattr__
实现之外,将属性分配给上述类型之一的类的实例应该引发AttributeError
。
在这些情况下,您将必须使用包装器,如下所示:
class AttrWrapper(object):
def __init__(self, wrapped):
self._wrapped = wrapped
def __getattr__(self, n):
return getattr(self._wrapped, n)
conn = AttrWrapper(sqlite3.connect(filepath))
答案 1 :(得分:2)
简单的实验:
In []: class Tst(object): pass
..:
In []: t= Tst()
In []: t.attr= 'is this valid?'
In []: t.attr
Out[]: 'is this valid?'
所以,确实似乎有可能这样做。
<强>更新强>
但是从documentation: SQLite是一个C库...... ,所以看起来你真的需要把它包起来。
答案 2 :(得分:0)
conn.a = 'foo',
或任何动态分配有效,如果conn
<type 'classobj'>.
类似的事情:
c=object()
c.e=1
会引发属性错误。另一方面:Python允许您进行梦幻般的元类编程:
>>>from new import classobj
>>>Foo2 = classobj('Foo2',(Foo,),{'bar':lambda self:'bar'})
>>>Foo2().bar()
>>>'bar'
>>>Foo2().say_foo()
>>>foo
答案 3 :(得分:-1)
这里的神奇词是“猴子补丁”。这是an SO answer的例子。