模块导入变量后为None
测试脚本
main.py:执行脚本
model_1.py:导入模块
——————————
代码如下:
# model_1.py
a = 1
b = None
def setb(_b):
global b
b = _b
# main.py
from model_1 import setb
from model_1 import a
from model_1 import b
setb(2)
print(a)
print(b)
代码意图在模块model_1中定义两个变量,一个在模块本身进行赋值,另一个在执行脚本中赋值。打印结果为
1
None
预期结果应该是打印b的时候打印赋值给他的2.
原因
原因在于from import语句导入b的时候,实际上是拷贝一份b到执行脚本中。import之后执行脚本的b和模块中的b就再也没有任何关联。而在导入的时候,对模块b的赋值还没有开始执行,所以拷贝过来的其实就是b的初始值None。
有时候,我们希望在模块中定义的变量在执行脚本中看情况进行初始化。为了拿到的b就是模块中的b,执行脚本应该这么写:
# main.py
import model_1 as m1
m1.setb(2)
print(m1.b)
即应该选择导入模块,而不是导入他的变量。
如何在python中调用cmd,运行另一个python脚本时打开一个新终端窗口?
问题描述
# main.py
subprocess.Popen("python a.py")
subprocess.Popen("python b.py")
上面是执行脚本main.py中的一段代码。当你在windows打开一个cmd终端窗口并运行main.py时,以上两个语句会开启两个子进程去执行两个shell命令,即运行另外两个python脚本 a.py 和 b.py 。但是,a.py 和 b.py 的log信息全部都会在当前cmd窗口中打印,和main.py的log信息混杂在一块儿。
为了能够清晰地分辨出哪条log是属于谁的,我们需要运行一个python脚本之前,打开一个新终端去运行它。
解决方案
# main.py
subprocess.Popen("python a.py",creationflags = subprocess.CREATE_NEW_CONSOLE)
subprocess.Popen("python b.py",creationflags = subprocess.CREATE_NEW_CONSOLE)
creationflags 是subprocess.Popen 类的构造函数的众多可选参数之一。这个参数将会开启一个新的cmd窗口来执行第一个参数表示的shell命令。
但是依然产生一个新的问题,就是打开的cmd窗口在shell命令执行完毕之后会自动关闭。
最终通过各种测试,到 2019/10/21 为止我采用的方案是:
在两个bat文件里面分别写入:
rem a.bat
python a.py
rem b.bat
python b.py
注意这里的rem是注释语句,我用来表明上述代码属于哪个bat文件,不用真的写在bat文件中。
然后 main.py 里面改写成:
# main.py
subprocess.Popen("start a.bat",shell=True)
subprocess.Popen("start b.bat",shell=True)
这里,shell = True
表明这里面是一个shell语句。start是windows cmd 命令的其中一个。如果没有特别指明参数,那么它会打开一个新的cmd终端执行后面的shell语句。当shell语句执行完毕之后,终端仍然存在。
C#调用python脚本后,路径错误
原本我的脚本当中路径都是使用相对路径类似'./pictures/icons/pic.png'
的方式查找工程里的资源。单独运行好好的,但是后来转成使用WPF工程去调用python脚本之后就出错了。在python中将./
表示的绝对路径打印出来,显示的是WPF的调试根目录。说明WPF调用python脚本时,python将当前工作根目录也改了。
解决方案
在python脚本中,一开始就指定为当前入口脚本所在的目录就行了。
import os
os.chdir(os.path.dirname(os.path.abspath(__file__)))
os.path.abspath(__file__)
获取当前文件所在的绝对路径,os.path.dirname(file_path)
获取一个绝对路径下的最后的子目录的绝对路径。