Python, проверьте тип объекта после циклического импорта

Вот два файла, foo.py и bar.py bar.py имеет...

from foo import *

...наверху. bar.py использует типы, определенные в foo.

При импорте bar.py из foo у меня возникают проблемы с определением типов объектов. Глядя на приведенный ниже пример, почему вызовы isinstance возвращают False? Как я могу проверить, являются ли эти типы одинаковыми?

Спасибо,

===== foo.py =====

#!/usr/bin/env python

class Spam(object):
    def __init__(self, x):
        self.x = x
    def funcA(self):
        print 'function a'
    def __str__(self):
        return 'Spam object %s' % repr(self.x)

class Eggs(object):
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z
    def funcB(self):
        print 'function b'
    def __str__(self):
        return "Eggs object (%s, %s, %s)" % (repr(self.x), repr(self.y), repr(self.z))

def main(fname):
    if not fname.endswith('.py'):
        raise Exception("Must be a .py file")
    module = __import__(fname[:-3])
    for item in module.DATA:
        if isinstance(item, Spam):
            item.funcA()
        elif isinstance(item, Eggs):
            item.funcB()
        print item

if __name__ == '__main__':
    import sys
    for fname in sys.argv[1:]:
        main(fname)
    sys.exit(0)

===== bar.py =====

from foo import *
DATA=[
Spam("hi"),
Spam("there"),
Eggs(1, 2, 3),
]

person eric.frederich    schedule 22.07.2011    source источник
comment
Можете ли вы показать, как вы вызываете эту программу и что она выводит?   -  person Ned Batchelder    schedule 22.07.2011


Ответы (2)


Вы пробовали печатать Spam, Eggs и тип item?

Spam is <class '__main__.Spam'>
Eggs is <class '__main__.Eggs'>
type of item is <class 'foo.Spam'>
Spam object 'hi'
type of item is <class 'foo.Spam'>
Spam object 'there'
type of item is <class 'foo.Eggs'>
Eggs object (1, 2, 3)

Модуль foo.py запускается дважды, один раз как основная программа и один раз, когда он импортируется bar.py.

В основной программе Spam и Eggs определяются как __main__.Spam и __main__.Eggs.

В импортированном модуле Spam и Eggs определяются как foo.Spam и foo.Eggs.

__main__.Spam != foo.Spam, __main__.Eggs != foo.Eggs.

person MRAB    schedule 22.07.2011

С:

if __name__ == '__main__':
    import sys
    main('bar.py')
    sys.exit(0)

Я получил :

Spam object 'hi'
Spam object 'there'
Eggs object (1, 2, 3)

Переместите код main и основную функцию в другой файл и импортируйте foo, и все будет работать.

#-- main.py --

import foo

def main(fname):
    if not fname.endswith('.py'):
        raise Exception("Must be a .py file")
    module = __import__(fname[:-3])
    for item in module.DATA:
        if isinstance(item, foo.Spam):
            item.funcA()
        elif isinstance(item, foo.Eggs):
            item.funcB()
        print item

if __name__ == '__main__':
    import sys
    main('bar.py')
    sys.exit(0)
person fabrizioM    schedule 22.07.2011
comment
Верно... Я хочу, чтобы он вызывал funcA и funcB, которые будут печатать другие вещи. - person eric.frederich; 23.07.2011