2009-11-22 1 views
1

У меня есть модуль python.Заполняющие значения в пространстве имен модулей

Я хочу заполнить некоторые значения для него во время выполнения, как это сделать.

Например. У меня есть список,

[ «A», «B», «C»]

Я создаю там классы с этими именами, и хотите, чтобы они доступны, как если бы я создал их обычно

for el in ['A', 'B', 'C']: 
    type(el, (object,), {}) 

ответ

5

Я могу придумать пару способов сделать это ... В порядке (то, что я считаю) лучшего к худшему, мы имеем:

Во-первых, установка атрибутов на текущем модуле

# The first way I had of grabbing the module: 
mod = __import__(__name__, fromlist=['nonempty']) 

# From Roger's suggestion: 
import sys 
mod = sys.modules[__name__] 

for name in ['A', 'B', 'C']: 
    class_ = type(name, (object,), {}) 
    setattr(mod, name, class_) 

print A, B, C 

во-вторых, установка в текущий глобалам Dict:

for name in ['A', 'B', 'C']: 
    class_ = type(name, (object,), {}) 
    globals()[name] = class_ 

print A, B, C 

Последний, используя Exec (EWW):

for name in ['A', 'B', 'C']: 
    class_ = type(name, (object,), {}) 
    exec "%s = class_" % name 

print A, B, C 

Я тестировал все три эти работы в автономном скрипте (где __name__ == "__main__") и как модуль в большем пакете.

EDIT: Что касается обсуждения метода 1 против метода 2 в комментариях, они оба делают одно и то же. Пространство имен модуля определяется в файле dict, хранящемся на модуле (here are the docs). С уровня модуля вы можете получить это через globals(), а снаружи вы можете получить к нему доступ через атрибуты или атрибут __dict__ модуля.

интерактивная сессия для демонстрации:

Python 2.6.4 (r264:75706, Nov 8 2009, 17:35:59) 
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import sys 
>>> mod = sys.modules[__name__] 
>>> mod.__dict__ is globals() 
True 
+1

Второй способ получит мой +1. Первый - рыбный, а третий - ewww. – u0b34a0f6ae

+2

Почему '__import__' вместо' sys.modules [__ name __] '? – 2009-11-22 15:02:19

+0

@kaizer: Первый - это то, что хочет OP: классы должны быть добавлены к атрибутам модуля (и из модуля, который все еще работает в этом случае), а не в глобальные. Похоже, что '__import__' по-прежнему использует его. Я думаю, что мы все согласны с частью EWW:;) – RedGlyph

2

Для создания классов динамически и сделать их доступными в модуле mymodule:

import mymodule 
for el in ['A', 'B', 'C']: 
    setattr(mymodule, el, type(el, (object,), {})) 

Для создания классов в текущем модуле, используйте подход в Mike's answer.

+0

Но как бы вы сделали это внутри 'mymodule'? – agiliq

+0

Проверьте ответ Майка - все его предложенные подходы должны хорошо работать. –

Смежные вопросы