回答
你不能,因爲可揀對象的類定義必須駐留在導入的模塊的作用域中。只要把你的課程放在模塊範圍內,你就可以走了。
這就是說,在Python中很少有一些黑客無法實現機器內部(在這種情況下是sys.modules),但我不會建議這樣做。
MyClass
定義是func
函數的局部變量。你不能直接創建它的一個實例,但你可以將它的函數映射到一個新的類,然後使用這個新的類,因爲它是原來的類。這裏有一個例子:
def func(params):
class MyClass(object):
some_param = 100
def __init__(self, *args):
print "args:", args
def blabla(self):
self.x = 123
print self.some_param
def getme(self):
print self.x
func.func_code
是func
功能的代碼,func.func_code.co_consts[2]
包含MyClass
定義的字節碼:
In : func.func_code.co_consts
Out:
(None,
'MyClass',
<code object MyClass at 0x164dcb0, file "<ipython-input-35-f53bebe124be>", line 2>)
所以我們需要爲MyClass
功能的字節碼:
In : eval(func.func_code.co_consts[2])
Out:
{'blabla': <function blabla at 0x24689b0>,
'__module__': '__main__',
'getme': <function getme at 0x2468938>,
'some_param': 100,
'__init__': <function __init__ at 0x219e398>}
最後我們創建一個帶有元類的新類,它指定了MyClass函數ns至新類:
def map_functions(name, bases, dict):
dict.update(eval(func.func_code.co_consts[2]))
return type(name, bases, dict)
class NewMyClass(object):
__metaclass__ = map_functions
n = NewMyClass(1, 2, 3, 4, 5)
>> args: (1, 2, 3, 4, 5)
n.blabla()
>> 100
n.getme()
>> 123
有趣......但我不清楚這是如何用來醃製函數中定義的類的實例 - 也不能醃製代碼對象。 – martineau 2012-08-04 18:42:58
您可以解決泡菜的要求,即類定義由包括類定義爲醃漬實例數據的字符串和exec()
uting它自己通過增加取儲存時要導入的__reduce__()
將類定義傳遞給可調用對象的方法。這裏有一個簡單的例子說明我的意思:
from textwrap import dedent
# Scaffolding
definition = dedent('''
class MyClass(object):
def __init__(self, attribute):
self.attribute = attribute
def __repr__(self):
return '{}({!r})'.format(self.__class__.__name__, self.attribute)
def __reduce__(self):
return instantiator, (definition, self.attribute)
''')
def instantiator(class_def, init_arg):
""" Create class and return an instance of it. """
exec(class_def)
TheClass = locals()['MyClass']
return TheClass(init_arg)
# Sample usage
import pickle
from io import BytesIO
stream = BytesIO() # use a memory-backed file for testing
obj = instantiator(definition, 'Foo') # create instance of class from definition
print('obj: {}'.format(obj))
pickle.dump(obj, stream)
stream.seek(0) # rewind
obj2 = pickle.load(stream)
print('obj2: {}'.format(obj2))
輸出:
obj: MyClass('Foo')
obj2: MyClass('Foo')
顯然,這是低效的,包括類定義字符串醃每一個類的實例,使冗餘可以使其不切實際的,這取決於涉及的類實例的數量。
這樣做有些困難,因爲Pickle默認使用用戶定義類中的對象的方式是創建類的新實例 - 使用對象的__class__.__name__
屬性在對象的原始模塊中檢索其類型。這意味着:pickling和unpickling只對在定義的模塊中定義明確名稱的類有效(默認情況下)。
當在函數內定義一個類時,usulay將不會有一個模塊級(即全局)變量,它保存在該函數內創建的每個類的名稱。
的泡菜和npickle的行爲可以通過對類__getstate__
和__setstate__
方法進行自定義 - 檢查docs
- 但即使是他們,這樣做是正確的動態類可能會非常棘手,但我設法創造的工作實現它爲另一個SO問題 - 在這裏檢查我的答案: Pickle a dynamically parameterized sub-class
- 1. 如何在函數中編寫一個Traversable實例,在Haskell中?
- 2. 如何訪問同一實例內的另一個類的函數?
- 3. 在一個類內的函數內調用一個函數
- 4. 在Python中的函數內寫入一個類:沒有對象
- 5. 在實例化時編寫一個類?
- 6. 如何在另一個類中創建一個類的實例
- 7. 追加/寫入一個實例的值
- 8. 在WCF內實例化一個類
- 9. 在另一個類的構造函數中實例化一個類的唯一實例
- 10. 實例另一個類實例的參數中的一類
- 11. 如何讓一個類的實例成爲Jena中另一個類的實例?
- 12. 如何在一個盒子內包裝一個div的實例
- 13. 測試一個構造函數實例化另一個類
- 14. 如何從類中的某個函數返回一個類的實例?
- 15. 參數是一個類的聲明函數,返回該類的一個實例?
- 16. 使用內部構造函數實例化一個類
- 17. 如何從Actionscript 3.0中的另一個類實例引用一個類實例?
- 18. 從Excel的一個實例寫入另一個打開的實例
- 19. 一個類實例
- 20. 如何使一個類的實例是另一個類
- 21. Java:如何將一個類傳遞給一個函數實例化
- 22. 如何在Scala的一個步驟中實例化內部類?
- 23. 如何從另一個函數訪問實例化類?
- 24. 如何編寫一個返回另一個函數的函數?
- 25. 如何實例化一個動態類內的子類型?
- 26. 如何獲得一個類的實例?
- 27. 如何獲得一個類的實例?
- 28. 如何創建一個類的實例?
- 29. 如何返回一個類的實例?
- 30. 如何刪除一個類的實例?
爲什麼不把你的類放到模塊範圍內? – XORcist 2012-08-04 09:04:53