Python中参数配置
Python中参数获取: sys.argv[]的用法
来源
Sys.argv[ ]其实就是一个列表,里边的项为用户输入的参数,关键就是要明白这参数是从程序外部输入的,而非代码本身的什么地方,要想看到它的效果就应该将程序保存了,从外部来运行程序并给出参数。我们从外部取得的参数可以是多个,所以获得的是一个列表(list),也就是说sys.argv其实可以看作是一个列表,所以才能用[]提取其中的元素。其第一个元素是程序本身,随后才依次是外部给予的参数。
import sys
a=sys.argv[0]
print(a)
#结果为:F:/project2/test.py
#即得到文件的路径
如果改为a=sys.argv[1],并在shell里运行test.py what,则输出为:what
如果多增加一些输入,将a=sys.argv[2:],在shell 里运行test.py a b c d ,则输出:[‘b’,‘c’,‘d’]
Python命令行解析argparse常用语法使用简介
python学习之argparse模块–忆臻
Python-argparse-命令行与参数解析
Python3 configparse模块(配置)
argparse.ArgumentParser()用法解析
add_argument() 方法的第一个参数
name or flags - 一个命名或者一个选项字符串的列表,例如 foo 或 -f, --foo
foo这样的就是一个命名,而事-或带--就是选项字符串。
required - 此命令行选项是否可省略 (仅选项可用)。
利用argparse.ArgumentParser(),可以方便的从外部传入参数,但是我们有时又需要调试程序,另就可以用–foo,然后再在主程序中添加来实现
parser = argparse.ArgumentParser(description='命令行中传入一个数字')
parser.add_argument('-integers',default=1,type=int, nargs='+',help='传入的数字')
args = parser.parse_args(['-integers','3'])
print(args)
#Namespace(integers=[3])
也可以再配合 required=False来实现,利用default来实现。(但是这种方法在jupyter notebook中不能用)
import argparse
parser = argparse.ArgumentParser(description='命令行中传入一个数字')
parser.add_argument('-integers',default=1,type=int, nargs='+',required=False,help='传入的数字')
args=parser.parse_args()
print(args)
#Namespace(integers=1)
python获取当前路径
来源
import os,sys
使用sys.path[0]、sys.argv[0]、os.getcwd()、os.path.abspath(file)、os.path.realpath(file)
sys.path是Python会去寻找模块的搜索路径列表,sys.path[0]和sys.argv[0]是一回事因为Python会自动把sys.argv[0]加入sys.path。
如果你在C:\test目录下执行python getpath\getpath.py,那么os.getcwd()会输出“C:\test”,sys.path[0]会输出“C:\test\getpath”。
如果你用py2exe模块把Python脚本编译为可执行文件,那么sys.path[0]的输出还会变化:
如果把依赖库用默认的方式打包为zip文件,那么sys.path[0]会输出“C:\test\getpath\libarary.zip”;
如果在setup.py里面指定zipfile=None参数,依赖库就会被打包到exe文件里面,那么sys.path[0]会输出“C:\test\getpath\getpath.exe”。
#!/bin/env python
#-*- encoding=utf8 -*-
import os,sys
if __name__=="__main__":
print "__file__=%s" % __file__
print "os.path.realpath(__file__)=%s" % os.path.realpath(__file__)
print "os.path.dirname(os.path.realpath(__file__))=%s" % os.path.dirname(os.path.realpath(__file__))
print "os.path.split(os.path.realpath(__file__))=%s" % os.path.split(os.path.realpath(__file__))[0]
print "os.path.abspath(__file__)=%s" % os.path.abspath(__file__)
print "os.getcwd()=%s" % os.getcwd()
print "sys.path[0]=%s" % sys.path[0]
print "sys.argv[0]=%s" % sys.argv[0]
输出结果:
D:\>python ./python_test/test_path.py
__file__=./python_test/test_path.py
os.path.realpath(__file__)=D:\python_test\test_path.py
os.path.dirname(os.path.realpath(__file__))=D:\python_test
os.path.split(os.path.realpath(__file__))=D:\python_test
os.path.abspath(__file__)=D:\python_test\test_path.py
os.getcwd()=D:\
sys.path[0]=D:\python_test
sys.argv[0]=./python_test/test_path.py
os.getcwd() “D:\”,取的是起始执行目录
sys.path[0]或sys.argv[0] “D:\python_test”,取的是被初始执行的脚本的所在目录
os.path.split(os.path.realpath(file))[0] “D:\python_test”,取的是__file__所在文件test_path.py的所在目录
正确获取当前的路径:
__file__是当前执行的文件
# 获取当前文件__file__的路径
print "os.path.realpath(__file__)=%s" % os.path.realpath(__file__)
# 获取当前文件__file__的所在目录
print "os.path.dirname(os.path.realpath(__file__))=%s" % os.path.dirname(os.path.realpath(__file__))
# 获取当前文件__file__的所在目录
print "os.path.split(os.path.realpath(__file__))=%s" % os.path.split(os.path.realpath(__file__))[0]
python sys.path.append()和sys.path.insert()
python重定向sys.stdin、sys.stdout和sys.stderr
来源
标准输入、标准输出和错误输出。
标准输入:一般是键盘。stdin对象为解释器提供输入字符流,一般使用raw_input()和input()函数。
例如:让用户输入信息
import sys
print("Please enter your name: ")
name = sys.stdin.readline()
print(name)
#在控制台会打印出Please enter your name:
#然后等待我们输入
#键入“你好”,下一行也会出现“你好”
再例如,a.py文件标准输出作为b.py文件标准输入:
python 把py文件编译为pyc文件
来源
python -m py_compile file.py
python -m py_compile /root/src/{file1,file2}.py
编译成pyc文件。
也可以写份脚本来做这事:
Code:
import py_compile
py_compile.compile('path') //path是包括.py文件名的路径
python -O -m py_compile file.py
编译成pyo文件。
1.其中的 -m 相当于脚本中的import,这里的-m py_compile 相当于上面的 import py_compile
2.-O 如果改成 -OO 则是删除相应的 pyo文件,具体帮助可以在控制台输入 python -h 查看
什么是pyc文件
pyc是一种二进制文件,是由py文件经过编译后,生成的文件,是一种byte code,py文件变成pyc文件后,加载的速度有所提高,而且pyc是一种跨平台的字节码,是由python的虚拟机来执行的,这个是类似于JAVA或者.NET的虚拟机的概念。pyc的内容,是跟python的版本相关的,不同版本编译后的pyc文件是不同的,2.5编译的pyc文件,2.4版本的 python是无法执行的。
什么是pyo文件
pyo是优化编译后的程序 python -O 源文件即可将源程序编译为pyo文件
什么是pyd文件
pyd是python的动态链接库。
为什么需要pyc文件
这个需求太明显了,因为py文件是可以直接看到源码的,如果你是开发商业软件的话,不可能把源码也泄漏出去吧?所以就需要编译为pyc后,再发布出去。当然,pyc文件也是可以反编译的,不同版本编译后的pyc文件是不同的,根据python源码中提供的opcode,可以根据pyc文件反编译出 py文件源码,网上可以找到一个反编译python2.3版本的pyc文件的工具,不过该工具从python2.4开始就要收费了,如果需要反编译出新版本的pyc文件的话,就需要自己动手了,不过你可以自己修改python的源代码中的opcode文件,重新编译 python,从而防止不法分子的破解。
生成单个pyc文件
python就是个好东西,它提供了内置的类库来实现把py文件编译为pyc文件,这个模块就是 py_compile 模块。
使用方法非常简单,如下所示,直接在idle中,就可以把一个py文件编译为pyc文件了。(假设在windows环境下)
import py_compile
py_compile.compile(r'H:\game\test.py')
compile函数原型:
compile(file[, cfile[, dfile[, doraise]]])
file 表示需要编译的py文件的路径
cfile 表示编译后的pyc文件名称和路径,默认为直接在file文件名后加c 或者 o,o表示优化的字节码
dfile 这个参数英文看不明白,请各位大大赐教。(鄙视下自己)原文:it is used as the name of the source file in error messages instead of file
doraise 可以是两个值,True或者False,如果为True,则会引发一个PyCompileError,否则如果编译文件出错,则会有一个错误,默认显示在sys.stderr中,而不会引发异常
批量生成pyc文件
一般来说,我们的工程都是在一个目录下的,一般不会说仅仅编译一个py文件而已,而是需要把整个文件夹下的py文件都编译为pyc文件,python又为了我们提供了另一个模块:compileall 。使用方法如下:
import compileall
compileall.compile_dir(r'H:\game')
也可以直接用命令行编译一个目录下的文件,如:# python -m compileall /root/src/
这样就把game目录,以及其子目录下的py文件编译为pyc文件了。嘿嘿,够方便吧。来看下compile_dir函数的说明:
compile_dir(dir[, maxlevels[, ddir[, force[, rx[, quiet]]]]])
dir 表示需要编译的文件夹位置
maxlevels 表示需要递归编译的子目录的层数,默认是10层,即默认会把10层子目录中的py文件编译为pyc
ddir 英文没明白,原文:it is used as the base path from which the filenames used in error messages will be generated。
force 如果为True,则会强制编译为pyc,即使现在的pyc文件是最新的,还会强制编译一次,pyc文件中包含有时间戳,python编译器会根据时间来决定,是否需要重新生成一次pyc文件
rx 表示一个正则表达式,比如可以排除掉不想要的目录,或者只有符合条件的目录才进行编译
quiet 如果为True,则编译后,不会在标准输出中,打印出信息
总结
通过上面的方法,可以方便的把py文件编译为pyc文件了,从而可以实现部分的源码隐藏,保证了python做商业化软件时,保证了部分的安全性吧,继续学习下,看怎么修改opcode。
另外
pyc文件就是 py程序编译后得到的字节码文件 (py->pyc),python为了提高运行效率也会进行编译,有时候编译出pyc文件后,删除py文件也不会出错
加入你有一个逻辑文件abcd.py,里面有很多函数A,B,C,D,这个时候,如果你有一个test脚本去导入了abcd.py,只要你运行test脚本,在adcd.py目录下就会生成一个abcd.pyc文件,而不管你是否需要调用A,B,C,D函数
运行.pyc文件
>>> Python test.pyc 即可
如何载入.pyc类型的模块
普通python应用中载入.pyc中模块
首先要保证调用程序的python版本与编译.pyc文件的python版本一致。
当我们执行调用原模块.py
的python程序时,会在该程序下生成一个.pyc文件,可能在同目录下生成一个__pycache__
文件夹,里面有一个与模块.py
同名并以.cpython-35.pyc
结尾的文件,此即为编译好的文件,这个文件能保证版本一致,我们可以将此文件改成模块.pyc
,然后放到调用程序可扫描的路径中,比如调用程序的同目录下,比如,python安装目录下,比如site-packages目录下,这样import该模块时,都能被扫描到,并且可以运行;当然我们也可以用上面的方式生成.pyc文件,只是要保证python版本一致;在from 模块 import 类
时,模块和类可能提示错误,但是不影响主程序的执行,大概是因为.pyc中是字节码,IDE中不能立马解析,导致语法检查时提示错误。
spark上载入.pyc中的模块
主程序中载入模块方法与前面一致,.pyc
文件即可以放在主程序同名的目录,但需要在spark-submit
时用--py-files
参数将该文件上传到spark集群;也可以将.pyc
文件放到python默认可扫描的目录下,比如site-packages
,但是需要在集群的每个机器上都上传一份,此时这个.pyc
文件就相当于是已经安装好的库了。
四年完成400万行Python代码检查,甚至顺手写了个编译器
Python打包
Python打包文件夹的方法小结(zip,tar,tar.gz等)
Python打包文件夹的方法小结(zip,tar,tar.gz等)
egg文件制作与安装
来源1、来源2
经常接触Python的同学可能会注意到,当需要安装第三方python包时,可能会用到easy_install命令。easy_install是由PEAK(Python Enterprise Application Kit)开发的setuptools包里带的一个命令,它用来安装egg包。egg包是目前最流行的python应用打包部署方式。
python的egg文件有点像java中的jar文件,是一个工程打包文件,便于安装部署。比如在spark-submit时主程序有多个文件依赖,就需要将这些文件通过特定参数上传;如果将这些文件打包上传、管理和引用都会比较方便。
egg文件的制作与使用,可以参考官方文档
egg文件的制作需要python已经安装setuptools 包。
制作egg文件
接下来我们就自己制作一个简单的egg包。 首先建立工程目录myeggdemo,初始化一个setup.py文件:
$ mkdir myeggdemo
$ cd myeggdemo
$ touch setup.py
$ ls
setup.py
下面主要就是填充setup.py。setup.py其实是python工具包distutils的配置文件,setuptools就是基于distutils来做的。 在setup.py中通过setup函数来配置打包信息。首先要引入setuptools的函数setup。setuptools的setup其实就是distutils的setup函数,填写setup.py为以下内容:setup函数接收一系列属性作为配置参数。
name name是egg包的名称,也是寻找要打包的文件夹的名称,默认是UNKNOWN。
version 版本号,默认0.0.0
packages 这里要用到setuptools的另一个函数find_packages,顾名思义,find_packages用来将指定目录下的文件打包。
zip_safe 默认是False,这样在每次生成egg包时都会检查项目文件的内容,确保无误。
还有一些描述性的属性,如description,long_description,author,author_email,license,keywords,platform,url等。 填充setup.py文件如下:
$ cat setup.py
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from setuptools import setup, find_packages
setup(
name = 'mydemo',
version = '0.1.0',
packages = find_packages('src'),
package_dir = {'':'src'},
description = "egg test mydemo",
long_description = "egg test demo.",
author = 'zhouguoqing',
author_email = 'zhouguoqing\@gmail.com',
license = 'GPL',
keywords = 'test api mydemo',
platforms = "Independant",
url = '',
)
在myeggdemo目录下建立和上述name名称相同的目录mydemo,mydemo目录下写__init__.py文件:
$ mkdir mydemo
$ > mydemo/__init__.py
空文件
$ vim mydemo/test.py
#!/usr/bin/env python
#-*- coding:utf-8 -*-
def test():
print("i'm egg demo")
def hello():
print("Hello egg ok.")
if __name__ == "__main__":
test()
hello()
再次生成egg包以后查看egg包信息:
$ python setup.py bdist_egg
可以看到,多了一个文件夹,先安装了体验一下再说:
$ sudo python setup.py install
egg文件使用
OK!安装完毕!接下来我们就可以直接通过import来使用啦!
from mydemo import test;
test.test();
test.hello()
#i'm egg demo
#Hello egg ok.
egg文件卸载
以python2.7版本为例,egg文件一般安装在/usr/local/lib/python2.7/dist-packages/目录下,该目录下还有一个easy-install.pth文件,用于
存放安装的egg信息。:
$ cd /usr/local/lib/python2.7/dist-packages
$ cat easy-install.pth|grep mydemo
./mydemo-0.1.0-py2.7.egg
$ ls -F|grep mydemo
mydemo-0.1.0-py2.7.egg/
卸载egg文件很简单,首先将包含此egg的行从easy-install.pth中删除,然后删除egg文件夹即可。
vim easy-install.pth 删除 ./mydemo-0.1.0-py2.7.egg 行
sudo rm -rf mydemo-0.1.0-py2.7.egg
Python包管理工具setuptools
py4j——用python访问java
py4j官网,上面有一个在python中使用java语法的demo.
开启JavaGateway
首先需要单独开启JavaGateway,可以写一个java程序去开启
#myPy4jServer.java
import py4j.GatewayServer;
public class myPy4jServer{
public static void main(String[] args) {
myPy4jServer app = new myPy4jServer();
// app is now the gateway.entry_point
GatewayServer server = new GatewayServer(app);
server.start();
}
}
编码此java源代码,需要将py4j-0.10.4.jar与源文件放在同一目录下
javac -classpath ./py4j-0.10.4.jar myPy4jServer.java
如下运行生成的应用,便启动了JavaGateway (可以以守护进程启动)
java -classpath .:./py4j-0.10.4.jar myPy4jServer
测试在python中使用java
#test.py
#-*-coding:utf-8-*-
from py4j.java_gateway import JavaGateway
gateway = JavaGateway()
random = gateway.jvm.java.util.Random()
number1 = random.nextInt(10)
number2 = random.nextInt(10)
print(number1, number2)
运行以上代码
python ./test.py
结果如下:
6 9
Python map() 函数
描述
map() 会根据提供的函数对指定序列做映射。
第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。
语法
map() 函数语法:
map(function, iterable, ...)
参数
- function – 函数,有两个参数
- iterable – 一个或多个序列
返回值
Python 2.x 返回列表。
Python 3.x 返回迭代器。
实例
以下实例展示了 map() 的使用方法:
>>>def square(x) : # 计算平方数
... return x ** 2
...
>>> map(square, [1,2,3,4,5]) # 计算列表各个元素的平方
[1, 4, 9, 16, 25]
>>> map(lambda x: x ** 2, [1, 2, 3, 4, 5]) # 使用 lambda 匿名函数
[1, 4, 9, 16, 25]
# 提供了两个列表,对相同位置的列表数据进行相加
>>> map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
[3, 7, 11, 15, 19]
python请求网页信息
来源:python+requests实现接口测试 - get与post请求使用
#-*-coding:utf-8-*-
import requests
import datetime
if __name__=="__main__":
dateCurrent = datetime.date.today()
for i in range(700):
datePre=dateCurrent-datetime.timedelta(days=i)
datePre = datePre.strftime('%Y%m%d')
urlStr='http://www.easybots.cn/api/holiday.php?d=%s'%(datePre)
r = requests.get(url=urlStr)
# if r.status_code==200:
temp=r.text
#{"20180824":"0"}
temp=temp[1:]
temp=temp[:-1]
temp=temp.split(sep=':')
print(temp)
Python3 爬取信息时TooManyRedirects错误解决方案
https://blog.csdn.net/Eugene_3972/article/details/78718035
Python计算程序运行时间
http://www.cnblogs.com/rookie-c/p/5827694.html
import datetime
starttime = datetime.datetime.now()
#long running
endtime = datetime.datetime.now()
# 正式中endtime - starttime得到的是datetime.timedelta,其包含三部分,timedelta.days,timedelta.seconds,timedelta.microseconds.所以下式中,如何运行时间超过一天那么,算出的时间就是错的。
print (endtime - starttime).seconds
#完整的应该将下面三部分加起来
starttime = datetime.datetime.strptime('2018-12-01 09:15:00','%Y-%m-%d %H:%M:%S')
#long running
endtime = datetime.datetime.strptime('2018-12-02 09:15:00','%Y-%m-%d %H:%M:%S')
a=endtime - starttime
print(a.days)
print(a.seconds)
print(a.microseconds)
Python time sleep()方法
Python 编程核心知识体系
pickle包
Python标准库05 存储对象 (pickle包,cPickle包)
python3使用pickle读取文件提示TypeError或者UnicodeDecodeError的解决办法
logging
记录程序中的运行日志或结果对程序调试、结果追踪都非常重要。最简单的方式是在程序内部将相关的结果或捕获到的错误输出到一个文件中去。但是 python 本身也有一些日志记录的工具。
Python logging 库分析
Python 学习入门(14)—— logging
不能精准定位bug?可能是你没get到这几个打印日志的诀窍!
详细规范的用法可参考Maskrcnn的源代码。