pycharm调用外部程序
应用场景:当公司项目成熟的时候,python代码会运行在 项目服务器上,需要对服务器进行一些操作,比如获取服务器的ip地址等信息,此时就需要用到如下库实现
有两种方法可以实现:os.system方法调用,subprocess库
- os.system
方法解释:等于打开操作系统的shell,敲入一串命令,比如ipconfig命令
import os
# 在shell终端 输入ipconfig
os.system('ipconfig')
print("after call")
# 在shell终端 打开 画图板
os.system('mspaint')
# 在shell终端进入 cmd工具
os.system('cmd.exe')
#在cmd命令行输入退出
os.system('exit')
操作问题:如果运行后乱码,需要在setting的file coding修改编码utf-8为GBK
阻塞式调用:调用外部程序如cmd.exe、系统的mspaint画板等时,如果没有主动退出,则python程序会一直停在那里,只有手动退出了,才会执行后面的代码
组装复杂参数:
os.system("for %i in (1, 2, 10) do @echo %i")
返回值:判断命令是否执行成功,如果执行成功,这个命令的返回值是0
命令执行失败会报错,返回值等于1
- subprocess
该库的check_output方法,可以实现调用外部程序,返回值就是执行结果,是byte类型,需要编码一下,可以使用utf-8,如果不行换用gbk编码(但是注意:需要等到被调用程序退出时才会有返回值)
该库的Popen类:①调用时会自动打印其输出的信息,②非阻塞式调用,在被调用程序运行时不会阻塞后面的代码,可以继续执行后面的代码。③且该函数在运行时,可以输入一些信息给被调用的程序
将Popen类赋值给一个对象,Popen的输出本来是直接打印在终端的,但是使用communicate方法将打印的标准输入重定向给了一个 返回值。
装饰器
装饰器组成: 自定义函数+ @函数
装饰器作用:使得执行到原函数时,不会执行原函数里得代码,而是转为执行装饰器新建得函数代码(起到了重新构造函数的效果)
学前理解:在讲解装饰器时,先熟悉一个概念:函数foo() 可以作为返回值,如 return foo。此时外层函数的返回值就是一个内部的函数foo,如果要实现内部函数的功能,需要调用外层函数然后加()继续调用foo 函数实现
def f():
print("888888")
def foo():
print("这是内部函数的内容")
return foo # 返回内部函数,但不调用
f() #调用外部函数,得到的返回值是一个函数foo
f()() #调用外部函数,得到foo,继续调用foo(),得到foo的调用结果
而装饰器,就是根据这一点来 实现,将 新加功能的函数 当成一个参数返回,当调用外部函数时,在后面加上() 就可以实现 内部函数的调用
1、装饰器引入:当需要 给函数进行新增功能时,可以将 已定义的函数,作为参数传递给另一个新函数如
def foo():
print("执行一系列接口测试")
time.sleep(1)
def bar(func):
startTime = time.yime
func() #调用该原有函数
endTime = time.time
print("总计时:",endTime- startTime)
#开始调用自己新建的函数,并把原有函数当作参数传入
bar(foo)
2、装饰器完善:但是!当其他 同事想拥有这个新功能时,就需要调用我自定义的新函数bar,而无法直接用foo函数实现。
所以,需要实现: 同事用到的foo函数,实际就是我定义的新函数bar;即foo() == bar(foo)
修改代码实现:将 新定义的函数操作内容,封装成一个inner函数,然后外层bar函数 直接返回inner函数(即实现inner函数的结果,会通过bar函数调用返回)
def foo():
print("执行一系列接口测试")
time.sleep(1)
def bar(func):
def inner():
startTime = time.yime
func() #调用该原有函数
endTime = time.time
print("总计时:",endTime- startTime)
此时,如果同事在使用时,先将我新建的函数赋值给foo,然后调用foo(),即可实现不改自己代码,也能有用到新加的功能
foo = bar(foo) # 同事使用时,额外需要 将自己定义的函数bar直接 赋值给foo
这个时候,同事每次用到foo,即foo() 时,相当于 bar(foo)(),调用了内部函数inner
3、装饰器优化
由于同事在使用时,都需要自己去定义赋值,所以python引入了语法行:@,@bar 表示bar是一个装饰器,且定义 foo = bar(foo)。
运行流程:先定义@bar,后续代码进行到foo() 时,不会执行foo()里面的代码,而是去执行装饰器里的代码
# 我给前同事的功能新加了功能
def bar(func):
def inner():
start_time = time.time()
func() # 调用该原有函数
end_time = time.time()
print("总计时:", end_time - start_time)
return inner
@bar
#前同事写的功能函数
def foo():
print("执行一系列接口测试")
time.sleep(1)
# 后同事开始 按照计划调用foo函数,此时的foo已经是bar(foo)了
foo()
4、带参的装饰器
如果原函数foo() 是一个带参的函数,则在定义装饰器的时候,需要将入参 定义在inner函数处,此时,inner里面调用原foo() 函数时,可以给foo传参