随着我们python的深入,必然需要引用外界的参数。那么常见的都有哪几种方式呢?
sys.argv----方便快捷
argparse.ArgumentParser()---提供全面的命令行传参
.pyc----------利用python库提供数据
.ini------------配置文件中读取
.format------对模板快速填充
fileinput.input()--------------------提供接收管道数据
目录:
- 命令行传参
1.1 简单命令行传参sys.argv
1.2 复杂命令行传参argparse.ArgumentParser() - 文件传参
2.0 读文件处理文本,file,不推荐
2.1 py文件传参,.py, .pyc
2.2 windows常见配置文件,.ini - 模板填充
3.1 使用format去填充一个文件模板。 - 数据流
4.1 Linux引用管道符
1. 命令行传参类
如果写脚本时需要从外界获取一个或几个简单的变量,那么可以直接读取sys模块的argv属性,从而获得一个记录了命令行内容的list。
1.1、sys.argv (sys:system系统, argv:Argument Values命令行参数)
sys.argv是用一个python的list类型,储存脚本本身的名称,以及命令行传入的参数
#filename=test_sys.py
import sys
argv_list = sys.argv # sys.argv是一个python的列表
fileName,myName, myHeight = argv_list
print(type(argv_list), argv_list)
执行
jiuyue@login$ python3 test_sys.py argrument1 argument2 # linux执行
<class 'list'> ['test_sys.py', 'argrument1', 'argument2'] # 输出内容
如果我们需要很复杂的传参,我们当然可以继续使用sys.argv, 但是我们有更好的解决方案--argparse模块(argument parse :参数去解析),argparse从名字我们就可以知道这时一个对sys.argv进行解析的模块。
1.2、argparse.ArgumentParser() (arg:Argument 参数, parse:v. 解析, parser:n.解析器)
argparse使用只需要三步, 获得解析器实例,添加参数, 解析参数值
代码示例:
#filename=test_sys.py
import argparse
import sys
parser = argparse.ArgumentParser() # step1
parser.add_argument('-f',dest="filename") # step2, 通过-f 传入参数
parser.add_argument(dest="test_filename") # step2, 通过位置传入参数,
parser.add_argument(dest="test2_filename") # step2, 通过位置传入参数,
args = parser.parse_args() # step3
print(args.filename)
print(args.test_filename)
print(args.test2_filename)
print(sys.argv)
执行
jiuyue@login4: python3 test_argparse.py file1.txt -f f_file.txt file2.txt
f_file.txt
file1.txt
file2.txt
['test_argparse.py', 'file1.txt', '-f', 'f_file.txt', 'file2.txt']
2. 文件传参
假设我们遇到一个业务场景,脚本版本1由A公司的小s和小b同学使用,版本2由B公司的小x和小w同学使用。在使用脚本时,我们不想频繁的改动主脚本,也不想客户每次都要输入公司名,那么我们的脚本需要从外界读取的参数分为两种,一种是刚刚提到的常常需要改的参数,另外一种是轻易不改的,我们可以使用一个文件进行记录轻易不改的相关参数。
2.0、读文件处理文本,file,不推荐
读一个纯文件,按照自己规则进行处理获得参数,因为需要自己考虑很多特殊问题(比如,空行,注释行,value中有注释),所以不推荐, 此处只做简单演示。
文件格式拟定为:一行为一个参数,key和value使用“=”分开。
jiuyue@login4: cat config.file
name = jiuyue
age=17
height =170
代码
def config_parse(config_file):
config_dict = {} # 使用字典容器保存参数
with open("./config.file") as f:
config = f.read().split("\n")
for line_raw in config:
line = line_raw.strip().split("#")[0] # 去除注释
if line == "": # 去除中间行
continue
key, value = [i.strip() for i in line.split("=")] # 去除等号两边的控制
config_dict[key] = value
return config_dict
print(config_parse(".config.file"))
执行
jiuyue@login4: python3 test_fileconfig.py
{'name': 'jiuyue', 'age': '17', 'height': '170'}
正如之前所说,如果传参文件比较复杂,那么操作需要处理很多细节,因为使用的是python,那么我们其实可以使用python文件进行构建一个传参。
2.1、使用python模块的方式进行传参
首先我们将要传入的变量写到一个可以修改的python格式的文件,然后用模块导入的方式导入变量
格式和遵循python编码规范,例如下面写一个dict,然后在主脚本中引用。
#filename = python_config.py
my_ID = {
"name": "jiuyue",
"age": 25,
"other": "IDgene",
}
在主脚本中导入已经定于的函数
#filename = test_main.py
import os
os.path.append("./") # 添加python_config.py所在的目录,作为python模块的搜索路径,
from my_config import my_ID # 注意这里是my_config而不是my_config.py
print(my_ID)
按照惯例,我们查看可以运行的结果
jiuyue@login4: python3 test_mian.py
{'name': 'jiuyue', 'age': 25, 'other': 'IDgene'}
2.3、常见配置文件.ini
.ini 文件是Initialization File的缩写,即初始化文件,是windows的系统配置文件所采用的存储格式, python有专门的模块去获取.ini格式的文件信息。
一个常见.ini文件
# filename = myconfig.ini
# 允许先使用prefix后定义
# 使用"="和使用":"是一致的
# 有注释写在单独的一行,否则会被认为是value的一部分
# bool值可以写true和false不区分大小写,也可以写1和0
[installation]
library=%(prefix)s/lib
prefix = /usr/local
[server]
port:8080
nworkers=32
log_errors=True
show_warnings=1
使用python读取这文件
# filename = test_configparser.py
from configparser import ConfigParser
cfg = ConfigParser()
cfg.read("myconfig.ini")
library = cfg.get("installation", "library") # 所有的参数都能用get去读成文本
port_str = cfg.get("server", "port")
port_int = cfg.getint("server", "port")
show_warnings = cfg.getboolean("server", "log_errors") # 对于bool值,更推荐getboolean,支持0和1转换为bool值
print(library, repr(port_str), repr(port_int), show_warnings)
我们可以查看一下我们的运行结果,可以看出8080,即server中port的值使用getint可以直接帮我们转换。一个问题是如果我们的值不标准,比如用getint去读了非整数,比如字母,那么脚本会报错中断。
jiuyue@login4: python3 test_configparser.py
/usr/local/lib '8080' 8080 True
3. 模板填充
3.1 使用format去填充一个文件模板。
无论是工作还是日常生活中,我们总会遇到不断重复的事情,比如邀请一群人去参加同一个聚会。过年给其他人发送拜年短信。我们常常会遇到模板一样,但是需要改关键词的需求。比如下面这个
hi,{name};
您好,我们是XXXX,因XXXXX,所以特邀您参加,地址XXXX,您的席位为{address}。祝好~
你的{relation}
XXXXXXX
可以看到,我在三个要替换的内容中使用了{name},{address}, {relation}, 那么我接下来可以直接,读取这个模板,并进行填充。
with open("example.txt") as f:
example_str = f.read()
jiuyue_str = example_str.format(name = "jiuyue",
address = "三桌7座",
relation = "friend",
)
print(jiuyue_str)
惯例,进行执行
jiuyue@login4: python3 test_format.py
hi,jiuyue;
您好,我们是XXXX,因XXXXX,所以特邀您参加,地址XXXX,您的席位为三桌7座。祝好~
你的friend
XXXXXXX
4. 数据流
4.1 Linux引用管道符
经常用Linux我们都知道linux中有管道的概念,比如下面将cat的内容传给awk
$cat example.txt |awk '{print NR,$1}'
1 hi,{name};
2 您好,我们是XXXX,因XXXXX,所以特邀您参加,地址XXXX,您的席位为{address}。祝好~
3 你的{relation}
4 XXXXXXX
我们可以使用fileinput, 使python也接收管道中的内容,使python脚本成为一连串命令中的一环
#!/user/bin/python3
# filename = filein.py
import fileinput
with fileinput.input() as f_input:
for line in f_input:
line = line.replace("X", "Z")
print(line, end="")
我们执行一下
$cat example.txt |python3 filein.py
hi,{name};
您好,我们是ZZZZ,因ZZZZZ,所以特邀您参加,地址ZZZZ,您的席位为{address}。祝好~
你的{relation}
ZZZZZZZ
我是九月,这是我“10篇主题文章”计划的第一篇, 码字不易,如果对您稍有帮助,你的点赞是对我最大的支持。
Reference
1、argparse官方文档:https://docs.python.org/zh-cn/3/library/argparse.html#module-argparse