簡體   English   中英

Python:將屬性動態添加到新型class / obj

[英]Python: dynamically add attributes to new-style class/obj

我可以動態地向新類(從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'

救命?

是的,除非該類使用__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))

簡單實驗:

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'>.

像:

    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

這里的魔術詞是“猴子修補”。 這是一個帶有示例的解答

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM