2015-04-07 2 views
1

У меня есть файл A.py:IronPython странное поведение

... 
from System.IO import Directory 
... 
execfile('B.py') 

и файл B.py:

... 
result = ['a','b'].Contains('a') 

Такое сочетание прекрасно работает. Но если я комментирую эту конкретную линию импорта в A.py затем B.py жалуется:

AttributeError: 'list' object has no attribute 'Contains'

Это выглядит странно для меня, особенно B.py в одиночку работает нормально.

Есть ли в модуле System.IO «переопределение списка»? Есть ли способ определить, что изменилось во время этого импорта? Или избегать такого странного поведения?

ответ

1

B.py сам по себе (по IPy 2.7.4) также приводит к ошибке, которую вы предоставили. Он должен, поскольку нет встроенного метода, который бы связывался для этого вызова. Вы также можете попытаться воспроизвести это на стандартном питоне, чтобы убедиться.

Способ, которым вы «включаете» B.py в A.py, имеет неотъемлемые риски и проблемы, по крайней мере, из-за отсутствия контроля над областью, в которой выполняется код в B. Если вы завершаете свой код в правильном модуле/классах, вы можете быть уверены, что проблем такого типа нет.

Это может (упрощенно, просто функция, нет классов и т.д.) выглядит следующим образом:

from B import getResult 
getResult() 
from System.IO import Directory 
getResult() 

и

def getResult(): 
    from System.IO import Directory 
    result = ['a','b'].Contains('a') 
    return result 

Как вы можете видеть функцию getResult может гарантировать, что весь импорт и другие свойства области являются правильными, и он будет работать независимо от того, имеет ли данный сайт вызова данный импорт.

Что касается того, почему импорт System.IO.Directory вызывает привязку к IronPython.dll!IronPython.Runtime.List.Contains(object value), неясно и потребует тщательного изучения внутренней реализации IronPython.

Если вы возражаете фактический импорт в System.IO.Directory, но не хотите, чтобы реорганизовать код, который вы могли бы пойти с LINQ for IronPython/ImportExtensions как бы обеспечить способ Contains, а также. Это не уменьшит, но фактически увеличит ваш импортный шаблон, но будет более точным.

import clr 
clr.AddReference("System.Core") 
import System 
clr.ImportExtensions(System.Linq) 

result = ['a','b'].Contains('a') 
+0

Спасибо, Саймон. В общем, вы правы. И это то, что я делаю - рефакторинг кода, чтобы следовать всем этим лучшим практикам. Этот код работал целую вечность, а затем, после моего рефакторинга, он начал производить такие странные результаты. Даже странно - и А, и В не используют этот Справочник, и это было причиной того, что я его удалил. Итак, теперь у меня должен быть этот импорт без причины. – Alex

+0

Я распространил свой ответ с подсказкой о том, как избежать «импорта побочных эффектов». –

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