Python:向新样式的类/obj动态添加属性
我可以动态地将属性添加到新样式类(从Python:向新样式的类/obj动态添加属性,python,attributes,metaprogramming,Python,Attributes,Metaprogramming,我可以动态地将属性添加到新样式类(从对象派生的类)的实例中吗 详情: 我正在使用sqlite3.Connection的一个实例。简单地扩展类不是一个选项,因为我不通过调用构造函数来获取实例;我通过调用sqlite3.connect()获得它 构建包装器并不能为我正在编写的代码节省大量的代码 Python 2.7.1 编辑 正确答案。但我仍然没有达到我的目标;sqlite3.Connection bar的实例我尝试通过以下方式设置属性(与对象的实例一样)。我总是得到一个属性错误: > con
对象
派生的类)的实例中吗
详情:
我正在使用sqlite3.Connection的一个实例。简单地扩展类不是一个选项,因为我不通过调用构造函数来获取实例;我通过调用sqlite3.connect()
获得它
构建包装器并不能为我正在编写的代码节省大量的代码
Python 2.7.1
编辑
正确答案。但我仍然没有达到我的目标;sqlite3.Connection bar的实例我尝试通过以下方式设置属性(与对象的实例一样)。我总是得到一个属性错误:
> 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'
conn=sqlite3.connect([filepath])
>康涅狄格州a='foo'
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
康涅狄格州a='foo'
AttributeError:“object”对象没有属性“a”
>conn.uuu setattr_uuuuu('a','foo'))
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
conn.uuu setattr_uuuuu('a','foo'))
AttributeError:“object”对象没有属性“a”
帮助?是,除非该类正在使用或通过重写阻止属性写入,或内部Python类,或本机实现的Python类(通常使用C) 您始终可以尝试设置属性。除了非常奇怪的
\uuuu setattr\uuuu
实现之外,将属性分配给上述类型之一的类的实例应该会引发属性错误。
在这些情况下,您必须使用包装器,如下所示:
class AttrWrapper(object):
def __init__(self, wrapped):
self._wrapped = wrapped
def __getattr__(self, n):
return getattr(self._wrapped, n)
conn = AttrWrapper(sqlite3.connect(filepath))
简单的实验:
In []: class Tst(object): pass
..:
In []: t= Tst()
In []: t.attr= 'is this valid?'
In []: t.attr
Out[]: 'is this valid?'
因此,似乎确实有可能做到这一点
更新:
但是从SQLite来看,它是一个C库…,所以您似乎真的需要包装它
conn.a = 'foo',
或任何动态赋值都是有效的,如果conn是
<type 'classobj'>.
将引发属性错误。另一方面:Python允许您进行出色的元类编程:
>>>from new import classobj
>>>Foo2 = classobj('Foo2',(Foo,),{'bar':lambda self:'bar'})
>>>Foo2().bar()
>>>'bar'
>>>Foo2().say_foo()
>>>foo
现在我知道您是正确的,但它不适用于sqlite3.Connection或对象本身的实例。(参见上面的编辑)有什么帮助吗?@JellicleCat都属于“内部Python类”。我用包装纸扩展了答案。你在问题中提到使用一个;但我不确定为什么它不能解决问题。如果此包装器不起作用,请使用失败的场景扩展您的问题(或此处的注释)。我现在知道您是正确的,但它不适用于sqlite3.Connection或对象本身的实例。(见上面的编辑)有什么帮助吗?@JellicleCat:更新了我的答案。你可以检查实际的dict以了解sqlite3在使用什么。但这可能是一个C例程,在这种情况下,您将被迫以某种方式包装它。+1。甚至object.\uuu setattr\uuuu(conn'a',foo')
也会引发AttributeError。有趣的问题!
>>>from new import classobj
>>>Foo2 = classobj('Foo2',(Foo,),{'bar':lambda self:'bar'})
>>>Foo2().bar()
>>>'bar'
>>>Foo2().say_foo()
>>>foo