'from x import variable'在python中有什么影响3



我今天感觉特别厚。 考虑

mod1.py

count = 0
def foo ():
global count
count = count + 1

mod2.py

import mod1
from mod1 import foo, count
print("mod1.count = ", mod1.count)
print("count = ", count)
foo()
print("mod1.count = ", mod1.count)
print("count = ", count)

我假设将计数导入 mod2 有效地将其全球化。

> python3 mod2.py
mod1.count =  0
count      =  0
mod1.count =  1
count      =  0

我显然有一些根本性的误解。 我假设导入本质上会使mod1.count和count别名,但事实并非如此。 我猜这与同时使用"导入"和"从导入"有关。

它们之间的区别可能在于可用性。

import module

允许您使用.运算符从模块访问方法。

from module import something

允许您使用something而不使用运算符引用模块.。 您也可以说它可以让您在全球范围内使用something

使用from方法,您将全局导入something。这并不意味着modulesomething已经消失了。它只是制作方法的新实例。 因此,当您同时导入modulesomething的实例时,您可以按任何一种方式访问something(无论是否使用.运算符(。

我想你已经回答了你自己的问题。它们不是别名,而是两个不同的对象,大概是因为它们存在于不同的命名空间中。您可以通过导入然后print(mod1.count is count).如果它们是别名,这将返回True

这是由于Python处理变量名称的方式。为了给解释提供一些基础,我用一个列表作为第二个导入的变量来扩展您的示例:

mod1.py

count = 0
lst = [1, 2, 3]
def update_count():
global count
count = count + 1
def update_lst():
lst.append(4)

test.py

import mod1
from mod1 import count, lst, update_count, update_lst
print("mod1.count = ", mod1.count)
print("count = ", count)
print("mod1.lst = ", mod1.lst)
print("lst = ", lst)
update_count()
update_lst()
print('nAfter updates: n')
print("mod1.count = ", mod1.count)
print("count = ", count)
print("mod1.lst = ", mod1.lst)
print("lst = ", lst)    

输出:

mod1.count =  0
count =  0
mod1.lst =  [1, 2, 3]
lst =  [1, 2, 3]
After updates: 
mod1.count =  1
count =  0
mod1.lst =  [1, 2, 3, 4]
lst =  [1, 2, 3, 4]

那么,发生了什么?

导入countlst时,将在脚本的命名空间中创建这些新名称。名称countmod1.count已经引用的整数对象0的另一个名称,而名称lstmod1.lst已经引用的列表的另一个名称。

当我们执行更新时,列表在模块中更新,但它仍然是同一个对象:mod1.lstlst仍然引用同一个对象。

对于mod1.count来说,情况就不同了,因为我们在count = count + 1中使这个名称指的是一个新对象,整数1。 现在,mod1.count引用整数对象1,而主脚本中的count仍然引用原始0对象。

所以,这只是正常的Python名称行为。

如果你还没有读过它,我推荐Ned Batchelder关于Python名称和值的经典事实和神话,它很好地解释了名称在Python中是如何工作的。

最新更新