Python:动态为新风格类/对象添加属性
我可以动态地给新式类的实例(也就是从 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'
有人能帮忙吗?
3 个回答
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
1
简单实验:
In []: class Tst(object): pass
..:
In []: t= Tst()
In []: t.attr= 'is this valid?'
In []: t.attr
Out[]: 'is this valid?'
所以,确实看起来是可以做到的。
更新:
但是根据文档的说法:SQLite是一个C语言库...,所以看起来你确实需要对它进行封装。
4
是的,除非这个类使用了 __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))