代码之家  ›  专栏  ›  技术社区  ›  Xolve

python中的导入是静态的,有什么解决方案吗?

  •  4
  • Xolve  · 技术社区  · 15 年前

    PY.PY:

    i = 10
    
    def fi():
        global i
        i = 99
    

    bar.py:

    import foo
    from foo import i
    
    print i, foo.i
    foo.fi()
    print i, foo.i
    

    这是有问题的。为什么 i 不改变时 foo.i 变化?

    4 回复  |  直到 15 年前
        1
  •  7
  •   Jarret Hardie    15 年前

    什么 import 确实在 bar.py 设置了一个名为 i 巴利 指向与所调用标识符相同地址的模块命名空间 foo.py 模块命名空间。

    这是一个重要的区别… bar.i 不是指向 foo.i 而是在内存中的同一空间中 10 认为 福奥 恰好同时指向。在python中,变量名不是内存空间…它们是指向内存空间的标识符。在bar中导入时,将设置本地命名空间标识符。

    您的代码直到 foo.fi() 当标识符 在foo.py中,名称空间更改为指向literal 99,它是内存中的一个对象,显然与10不同。模块级命名空间dict for foo 在内存中标识与标识符不同的对象 在巴黎。

    Shane和Rossfaricant对如何调整模块以实现您想要的目标有很好的建议。

        2
  •  8
  •   Shane C. Mason    15 年前

    罗斯所说的是像这样重建foo:

    _i = 10
    
    def getI():
        return _i
    
    def fi():
        global _i
        _i = 99
    

    然后你会看到它按你想要的方式工作:

    >>> import foo
    >>> print foo.getI()
    10
    >>> foo.fi()
    >>> print foo.getI()
    99
    

    从某种意义上说,避免导出全局变量,但仍然提供对全局变量的读访问,这也是“更好的”。

        3
  •  3
  •   nosklo    15 年前

    i 里面 foo.py 是一个 不同的 从其中之一 bar.py . 在什么时候 巴利 你这样做:

    from foo import i
    

    创造了一个新的 在里面 巴利 那个 引用同一对象 作为 在里面 P.Py .

    你的问题是:当你打电话的时候 foo.fi() 它做到了:

    i = 99
    

    这项任务使 P.Py 指向另一个整数对象( 99 )整数对象本身是不可变的(谢天谢地),因此它只改变 P.Py 正在指向。不是 巴利 . 巴利 仍然指向它以前指向的旧对象。(整数不可变对象 10 )

    您可以通过将以下命令置于 巴利 :

    print foo.i
    

    应该打印 九十九 .

        4
  •  0
  •   RossFabricant    15 年前

    可以调用函数而不是引用全局变量。