【问题标题】:IronPython strange behaviourIronPython 奇怪的行为
【发布时间】:2015-04-07 20:08:39
【问题描述】:

我有文件 A.py:

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

和文件 B.py:

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

这样的组合效果很好。 但是,如果我在 A.py 中评论这个特定的导入行,那么 B.py 就会抱怨:

AttributeError: 'list' 对象没有属性 'Contains'

对我来说看起来很奇怪,尤其是 B.py 单独运行良好。

模块 System.IO 中是否有一些“列表”覆盖?有没有办法确定这个导入过程中发生了什么变化?还是避免这种奇怪的行为?

【问题讨论】:

    标签: python ironpython


    【解决方案1】:

    B.py 本身(在 IPy 2.7.4 上)也会导致您提供的错误。它应该是因为没有内置方法可以绑定该调用。您也可以尝试在标准 python 上重现它以确保。

    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')
    

    【讨论】:

    • 谢谢,西蒙。一般来说,你是对的。这就是我所做的——重构代码以遵循所有这些最佳实践。这段代码工作了很长时间,然后,在我重构之后,它开始产生如此奇怪的结果。甚至奇怪 - A 和 B 都不使用此目录,这就是我删除它的原因。所以,现在我必须无缘无故地进行此导入。
    • 我扩展了我的答案,提示如何避免“副作用导入”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-08
    • 2015-07-20
    • 2010-10-03
    • 2021-07-12
    • 2013-10-04
    相关资源
    最近更新 更多