2015-09-15 1 views
5

Я делаю модуль, который я хочу рассматривать как статический контейнер объектов. Эти объекты имеют тип класса, который я определил. Я хочу, чтобы иметь возможность импортировать этот модуль, а затем цикл через объекты внутри. Вот какой-то код объяснить, что я имею в виду:Можно ли сделать модуль итерабельным в Python?

example.py

class MyExampleClass(object): 
    def __init__(self, var1, var2, var3): 
     self.var1 = var1 
     self.var2 = var2 
     self.var3 = var3 
     self.var4 = var4 

instanceA = MyExampleClass(1, 2, 3, 4) 
instanceB = MyExampleClass(4, 3, 6, 7) 
instanceC = MyExampleClass(5, 3, 4, 5) 

# something like this 
def __iter__(): 
    return (instanceA, instanceB, instanceC) 

Тогда я хотел бы иметь возможность импортировать это и использовать его как перечисление:

import example 

for e in example: 
    # do stuff with e 

Is это можно сделать в Python? Или мне нужно будет импортировать список из пакета example?

example.py

objects = (instanceA, instanceB, instanceC) 

, а затем

import example 

for e in example.objects: 
    # do stuff with e 
+3

Второе решение, безусловно, работает. Почему бы не использовать его? – mdurant

+2

, или если вам почему-то не нравится эта версия, эквивалент 'из экземпляра объектов импорта; для e в объектах: '... –

+1

Возможно, вы можете сделать это, если вы нанесете некоторый объект в sys.modules, у которого есть правильный API для итерации. Не уверен, что это должно быть получено из 'ModuleType.' – schlenk

ответ

3

Вы можете достичь этого путем определения корневого класса в модуле и замены модуля с экземпляром этого класса. Вот пример:

class ModuleClass(object): 
    __init__(self): 
     self.instanceA = MyExampleClass(1, 2, 3, 4) 
     ... 

    __iter__(self): 
     # Your iterator logic here 

# and then in the same module code 
sys.modules[__name__] = ModuleClass() 

Итак, вы можете сделать то, что вы хотите, потому что, когда вы импортировать этот модуль, он на самом деле будет экземпляром пользовательских Iterable ModuleClass:

import example 

for e in example: 
    # do stuff with e 
+0

Это не работает, если я пытаюсь импортировать 'example' в два отдельных файла; первый файл правильно считает, что 'example' является экземпляром' ModuleClass', но второй файл по-прежнему считает, что 'example' является модулем – ahuff44

+0

Хмм интересно, можете ли вы опубликовать некоторые ошибки? – bagrat

+0

Мой плохой; Должно быть, я ошибся. Когда я создал новый проект, чтобы проверить это, ошибки не прошли – ahuff44

3

Хотя я не рекомендуется, вы можете создать свой собственный модуль, наследуя от types.ModuleType. Затем вы можете заменить исходный модуль на свой собственный класс sys.modules[__name__] = NewModule()

import types 
import sys 

class MyExampleClass(object): 
    def __init__(self, var1, var2, var3, var4): 
     self.var1 = var1 
     self.var2 = var2 
     self.var3 = var3 
     self.var4 = var4 

class MyModule(types.ModuleType): 

    def __init__(self, *args, **kwargs): 
     super().__init__(*args, **kwargs) 
     self.instanceA = MyExampleClass(1, 2, 3, 4) 
     self.instanceB = MyExampleClass(4, 3, 6, 7) 
     self.instanceC = MyExampleClass(5, 3, 4, 5) 

    def __iter__(self): 
     return iter([self.instanceA, self.instanceB, self.instanceC]) 

sys.modules[__name__] = MyModule("example") # Name of the module 
+0

Just Ugh .... Я вижу, почему это не рекомендуется. –