简体   繁体   English

Python:将属性动态添加到新型class / obj

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM