2013-06-24 2 views
0

У меня есть список экземпляров блока контента, которые по мере обработки списка содержимого для каждого блока генерируются в экземпляре класса типа контента (если это имеет смысл).Python: пытается установить атрибуты экземпляра класса из экземпляра другого экземпляра класса

Поскольку я перебираю список, я пытаюсь установить атрибуты экземпляра модулей с выходом из экземпляра именованного модуля из extra_modules. Если есть лучший способ написать этот вопрос, не стесняйтесь редактировать.

Ниже приведен пример кода тестирования, который я пытаюсь запустить, используя фреймворк Python Bottle. Я пытаюсь получить тестовый результат, прежде чем я на самом деле поставлю код создания контента в класс photoGallery.

core.py:

import extra_modules 

module_blocks_in_db = [ 
    # module-ID, module-sys-name, module-sys-desc, module-function, module-variables 
    [1, 'photo_gallery_main', 'A little intro gallery', 'photoGallery', '{"images": ["photo1.jpg", "photo2.jpg", "photo3.jpg"]}'], 
] 


class moduleBlocks: 
    def __init__(self, mbidb): 
     for i in mbidb: 
      setattr(self, i[1], getattr(extra_modules, i[3])(i[4])) 


@route('/') 
def home(): 
    page_id = 1 
    modules = moduleBlocks(module_blocks_in_db) 
    return modules.photo_gallery_main 

extra_modules.py:

class photoGallery: 
    def __init__(self, *args): 
     self.output = 'Output from photoGallery class instance' 
     return self.output 

Это ошибка, я получаю от сервера разработки бутылки:

File "core.py", line 46, in __init__ 
setattr(self, i[1], getattr(extra_modules, i[3])(i[4])) 
TypeError: __init__() should return None 

Я действительно не понимая эту ошибку, и чем больше я смотрю на код, тем больше я сбиваю с толку. Теперь я попытался несколько разных способов захватить вывод из экземпляра класса и назначить его как атрибут класса moduleBlocks в моем примере. Где я ошибаюсь?

EDIT: Теперь я изменил мою SetAttr линии на две отдельных линии и избавился от выхода возвратного в классе extra_modules ФОТОГалереи и вещи теперь работают отлично, спасибо:

x = getattr(extra_modules, i[3])(i[4]) 
setattr(self, i[1], x.output) 
+0

Что вы пытаетесь делать с этой линией? 'setattr (self, i [1], getattr (extra_modules, i [3]) (i [4]))' – mbatchkarov

+0

Я использую getattr для создания экземпляра класса photoGallery, который в def __init__ генерирует контент и возвращает вывод. Затем я хочу установить соответствующий атрибут экземпляра moduleBlocks с этим выходом. –

ответ

2

неправильно:

class photoGallery: 
    def __init__(self, *args): 
     self.output = 'Output from photoGallery class instance' 
     return self.output 

«_ инициализация _» является конструктором ФОТОГалереи, который несет ответственность за инициализацию объекта фотогалереи. Таким образом, нет смысла возвращать что-либо. Избавьтесь от возврата self.output и повторите попытку

+0

Итак, self.output установлен, но как мне вернуть значение self.output в этой строке: 'setattr (self, i [1], getattr (extra_modules, i [3]) (i [4]))' –

+0

@ zilog6502: сам объект 'photoGallery' является результатом этого вызова. Что ты пытаешься сделать? –

0

Хорошо, я думаю, посмотрим, что вы пытаетесь сделать, и я могу сказать вам, что этот подход проблематичен, мягко говоря. Проблема заключается в том, что вы пытаетесь получить доступ к каждой выходной переменной класса, необходимой для каждого создаваемого класса контроллера, чтобы определить выходную переменную, и необходимо документировать, что каждый контроллер должен определить выходную переменную.

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

Итак, вот некоторые варианты для вас.

  1. Вам действительно нужна фотогалерея как класс. Если все это делает, оно возвращает строку, и нет никакого взаимодействия или изменения состояния, для нее нет никакого смысла быть классом. измените его и аналогичные контроллеры на функцию, и это все, что вам нужно сделать.

  2. Возможно, есть какое-то изменение состояния, происходящее с ним в другом месте, тогда моя рекомендация должна быть прозрачной. У python нет интерфейсов, но у него есть abc (абстрактный базовый класс). вы можете сделать все, что вы наследуете от abc, и определить метод get_ouput.то вы бы:

    SetAttr (. самостоятельная, я [1], GETATTR (extra_modules, я [3]) (я [4]) get_output())

  3. Не рекомендую это как его действительно противный и будет немного позже вы:

    SetAttr (я, я [1], GetAttr (extra_modules, я [3]) (I [4]) выход.)

+0

Мне нравится номер 1 ваших решений здесь. Мне удалось заставить его работать с использованием классов и возглавлял этот путь, потому что я хотел использовать классы, такие как плагин, но мне очень нравится простота функций, спасибо. –