0%

argsparse是python的命令行解析的标准模块,内置于python,不需要安装。
这个库可以让我们直接在命令行中就可以向程序中传入参数并让程序运行。

argparse定义四个步骤

  1. 导入argparse包 ——import argparse
  2. 创建一个命令行解析器对象 ——创建 ArgumentParser() 对象
  3. 给解析器添加命令行参数 ——调用add_argument() 方法添加参数
  4. 解析命令行的参数 ——使用 parse_args() 解析添加的参数

举个例子如下:

.. literalinclude:: ../../src/python-argparse.py

默认输出如下所示:

.. code::bash

$ python src/python-argparse.py
Namespace(name=’Zhang San’, age=18)
Name : Zhang San Age : 18

sgguo@LENOVO-P71-LEO MINGW64 ~/OneDrive/mycode/3-Minutes-Programming/python (master)
$ python src/python-argparse.py –help
usage: python-argparse.py [-h] [–name NAME] [–age AGE]

Demo of argparse

optional arguments:
-h, –help show this help message and exit
–name NAME
–age AGE

Python 编写一个自己的包

这个教程将会指导你开发一个属于自己的python包,
还包含如何添加必要的文件以及包的结构,
最后说说如何编译并上传该文件。

简单示例

假定工程的名称为:example_pkg,需要创建下列目录结构:

1
2
3
packaging_tutorial/
example_pkg/
__init__.py

下面所有的操作均在目录中packaging_tutorial进行。

example_pkg/init.py is required to import the directory as a package, and can simply be an empty file.

创建package文件

标准package起始最好包含以下文件,

1
2
3
4
5
6
7
packaging_tutorial/
example_pkg/
__init__.py
tests/
setup.py
LICENSE
README.md

创建test文件夹

tests/主要用来存放unit测试文件,此时先留空。

创建 setup.py

setup.py文件用于编译,内容主要包含package的名字、版本、描述等等信息。

示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import setuptools

with open("README.md", "r") as fh:
long_description = fh.read()

setuptools.setup(
name="example-pkg-YOUR-USERNAME-HERE", # Replace with your own username
version="0.0.1",
author="Example Author",
author_email="author@example.com",
description="A small example package",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/pypa/sampleproject",
packages=setuptools.find_packages(),
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires='>=3.6',
)

setup() 的几个最必须的参数如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
name is the distribution name of your package. This can be any name as long as only contains letters, numbers, _ , and -. It also must not already be taken on pypi.org. Be sure to update this with your username, as this ensures you won’t try to upload a package with the same name as one which already exists when you upload the package.

version is the package version see PEP 440 for more details on versions.

author and author_email are used to identify the author of the package.

description is a short, one-sentence summary of the package.

long_description is a detailed description of the package. This is shown on the package detail package on the Python Package Index. In this case, the long description is loaded from README.md which is a common pattern.

long_description_content_type tells the index what type of markup is used for the long description. In this case, it’s Markdown.

url is the URL for the homepage of the project. For many projects, this will just be a link to GitHub, GitLab, Bitbucket, or similar code hosting service.

packages is a list of all Python import packages that should be included in the distribution package. Instead of listing each package manually, we can use find_packages() to automatically discover all packages and subpackages. In this case, the list of packages will be example_pkg as that’s the only package present.

classifiers gives the index and pip some additional metadata about your package. In this case, the package is only compatible with Python 3, is licensed under the MIT license, and is OS-independent. You should always include at least which version(s) of Python your package works on, which license your package is available under, and which operating systems your package will work on. For a complete list of classifiers, see https://pypi.org/classifiers/.

创建README.md

创建 README.md ,写上你准备写入的内容:

1
2
3
4
5
# Example Package

This is a simple example package. You can use
[Github-flavored Markdown](https://guides.github.com/features/mastering-markdown/)
to write your content.

创建LICENSE

比如使用MIT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Copyright (c) 2018 The Python Packaging Authority

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

生成发布包

接下来我们生成发布的软件包

1
$ python3 setup.py sdist bdist_wheel

这个命令会生成两个文件:

1
2
3
dist/
example_pkg_YOUR_USERNAME_HERE-0.0.1-py3-none-any.whl
example_pkg_YOUR_USERNAME_HERE-0.0.1.tar.gz

其中 tar.gz 文件为源码,.whl为编译的包。

比较新的pip可以直接按照whl格式的编译包。

一般而言,我们都需要上次源码以及编译包。

参考

代码参考 https://www.github.com/shaoguangleo/atas/python

锁屏利器Nearlock

给大家推荐一款Mac的锁屏利器Nearlock。

这个软件的slogan是Lock and unlock your Mac with your iPhone

不过这个有个硬性条件,就是需要同时拥有Mac和iPhone,Mac可以是MBP、MB、iMac、iWatch等系列产品。

Nearlock使用比较方便,软件通过蓝牙来判断Mac和iPhone的距离,从而通过设置来开启或者锁定Mac,这个对于临时有急事而又来不及锁屏的哥们来说还是很不错的,特别是进入办公室以后,做到座位上,不用任何操作,自动解锁,进入系统,OK,开始干活。

Nearlock有免费版,不过Pro版支持后台运行,喜欢就入手吧。

Mac OSX 安装Python3和pip3

Python2即将在2020年迎来它最后的时光,
或许现在你应该或者必须切换到Python3版本了。

下面简单说一下在Mac OSX上安装Python3和pip3的步骤

安装 python3

打开Python的 (官网)[https://www.python.org/] 下载python3的 OS X 版本,
应该是一个pkg文件。
双击安装,默认情况下会把pip3也安装上。

Python的版本可以通过下面的命令来查看。

1
$python3 --version

Install pip3:

pip3也可以通过下面的方式来安装:

1
2
$ curl https://pip.pypa.io/en/stable/installing/get-pip.py
$ python3 get-pip.py

可以通过下面的命令来确定pip3是否安装完成

1
$ which pip3

Python 格式化字符串

Python的格式化输出方法很多,相比较于C还是有很多便捷的方面。
下面开始说说。

格式化操作符 %

%是Python风格的字符串格式化字符串,与C语言中的printf函数的字符串类似。

下面是一些格式化的集合

格式化符号 说明
%c 转换成字符串
%r 优先使用repr函数进行字符串转换
%s 优先用str函数进行字符串转换
%d %i 转成有符号十进制
%u 转成无符号十进制
%o 转成无符号八进制
%x %X 转成无符号十六进制,x/X表示小大写
%e %E 转成科学计数法,e/E控制输出e/E
%f %F 转成浮点数
%g %G %e与%f的简写
%% 输出%

示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
a = 'x'
string = 'hello world\n'
n = 12
f = 3.1415

print ('%c' % a)
print ('%r' % string)
print ('%s' % string)
print ('%d' % n)
print ('%i' % n)
print ('%u' % n)
print ('%o' % n)
print ('%x' % n)
print ('%X' % n)
print ('%f' % f)
print ('%F' % f)
print ('%e' % f)
print ('%E' % f)
print ('%g' % f)
print ('%G' % f)

输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
x
'hello world\n'
hello world

12
12
12
14
c
C
3.141500
3.141500
3.141500e+00
3.141500E+00
3.1415
3.1415

这里比较需要留意的是str与repr两个内建函数之间的差异。

格式化操作符辅助符号

如果希望输出的时候美化输出,通常下面的一些辅助符号会起到比较好的作用。

辅助符 作用
* 定义宽度或者小数点精度
- 左对齐
+ 在正数前面加上加号+
# 在八进制前面显示0,十六进制前面加上0x或者0X,取决于用的是x还是X
0 显示的数字前面填充0而不是默认的空格
(var) 映射变量,通常用来吹了字段类型的参数
m.n m是显示的最小总宽度,n表示的是小数点后面的位数

示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
n = 1234
f = 3.1415926
students = [{'name': 'Han Meimei', 'age': 17}, {'name': 'Li Lei', 'age': 18}, {'name': 'Wei Hua', 'age': 17}]

print('%d => hex => %x' % (n, n))
print('%d => hex => %X' % (n, n))
print('%d => hex => %#x' % (n, n))
print('%d => hex => %#X' % (n, n))
print('value f is %f' % f)
print('value f is %.4f' % f)
print('name: %10s, age: %10d' % (students[0]['name'], students[0]['age']))
print('name: %-10s, age: %-10d' % (students[1]['name'], students[1]['age']))
print('name: %*s, age: %0*d' % (10, students[1]['name'], 10, students[1]['age']))

for student in students:
print('%(name)s is %(age)d years old' % student)

输出结果如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
1234 => hex => 4d2
1234 => hex => 4D2
1234 => hex => 0x4d2
1234 => hex => 0X4D2
value f is 3.141593
value f is 3.1416
name: Han Meimei, age: 17
name: Li Lei , age: 18
name: Li Lei, age: 0000000018
Han Meimei is 17 years old
Li Lei is 18 years old
Wei Hua is 17 years old

字符串模板

示例如下:

1
2
3
4
5
6
7
from string import Template

s = Template('Hi, $name! $name is $age years old.')
print(s.substitute(name='Han Meimei', age='17'))

hmm = {'name' : 'Han Meimei', 'age': 17}
print(s.substitute(hmm))

输出结果如下:

1
2
Hi, Han Meimei! Han Meimei is 17 years old.
Hi, Han Meimei! Han Meimei is 17 years old.

字符串内建函数format

从Python2.6开始,新增了一种格式化字符串的字符串str.format,通过这个函数可以对字符串进行格式化处理。在format函数中,使用{}符号来当做格式化操作符。

示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 位置参数

print('{0} is {1} years old.'.format('lily', 18))
print('{} is {} years old.'.format('lily', 18))
print('Hi {0}. {0} is {1} years old.'.format('lily', 18))

# 关键字参数
print('{name} is {age} years old'.format(name='lily', age=18))

# 下标参数
lily = ['lily', 18]
print('{0[0]} is {0[1]} years old'.format(lily))

# 填充与对齐
# ^<>分别表示居中、左对齐、右对齐,后面带宽度
# :后面带填充的字符,只能是一个字符,不知道的的话用空格填充

print('{:>8}'.format('3.14'))
print('{:<8}'.format('3.14'))
print('{:^8}'.format('3.14'))
print('{:0>8}'.format('3.14'))
print('{:a>8}'.format('3.14'))

# 浮点数精度
print('{:.4f}'.format(3.1415926))
print('{:0>10.4f}'.format(3.1415926))

# 进制
# b/d/o/x分别表示二进制、十进制、八进制、十六进制
print('{:b}'.format(12))
print('{:d}'.format(12))
print('{:o}'.format(12))
print('{:x}'.format(12))
print('{:#x}'.format(12))
print('{:#X}'.format(12))

# 千位分隔符
print('{:,}'.format(1230000000))

输出结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
lily is 18 years old.
lily is 18 years old.
Hi lily. lily is 18 years old.
lily is 18 years old
lily is 18 years old
3.14
3.14
3.14
00003.14
aaaa3.14
3.1416
00003.1416
1100
12
14
c
0xc
0XC
1,230,000,000

构建Python开源包

项目创建

按照需求,一般需要创建如下目录及文件:

1
2
3
4
5
6
7
$ tree .
.
├── LICENSE
├── README.md
├── docs
├── example
└── tests

搭建虚拟运行环境

在搭建自己的库的时候,如果希望有一个干净的项目环境的,可以使用virtualenv。
方便为后面生成私有项目的 requirement.txt 依赖包文件。

可以使用source ~/virtual/bin/activate进入环境,使用pip freeze > requirement.txt来生成依赖包文件。

编写项目代码

这一步主要为构建代码的原型架构以及代码,每个包都需要包含一个’init.py’文件。

编写安装脚本

在包的根目录创建文件setup.py,内容一般如下所示:

.. literalinclude:: ../../src/python-package-demo/setup.py

编写文档

进入docs文件夹,运行sphinx-quickstart,然后编写相应的rst文件即可。

默认的index.rst的内容如下:

.. literalinclude:: ../../../src/python-package-demo/docs/index.rst

Python 创建文件夹

os.mkdir() 方法

os.mkdir() 方法用于以数字权限模式创建目录。默认的模式为 0777 (八进制)。

如果目录有多级,则创建最后一级,如果最后一级目录的上级目录有不存在的,则会抛出一个 OSError。
语法

mkdir()方法语法格式如下:

1
os.mkdir(path[, mode])

参数

  • path – 要创建的目录,可以是相对或者绝对路径。
  • mode – 要为目录设置的权限数字模式。

返回值

该方法没有返回值。

实例
以下实例演示了 mkdir() 方法的使用:

.. literalinclude:: ../../src/python-mkdir.py

执行以上程序输出结果为:

1
Created

Git核弹级指令

核弹级这个概念应该是Pro Git的作者说的,这就说明了这个指令的强悍指出,除非特别清楚你准备干什么。

否则不要抱着尝试的想法来试试,除非你想尝试下核弹的威力。

其实用到这个指令主要是因为以前是自己做的局域网Git,文件的大小没有多少限制,比如几百兆的文件我也给放上去了。

但是碰到将这个repo公开到github上的时候,就碰到这个问题了。

1
remote : error: GH001: Large files detected.

当然处理方法还是有的,就是使用git的lfs,不过不太像折腾,索性使用核弹指令。

具体的命令如下,其中big_file为准备删除的文件,含义就是讲大文件从以前8次的提交中删除,
注意是从提交中删除,所以意思就是以前所有的提交都是可以修改的,OMG,这是什么意思,让我静静。

1
2
$ git filter-branch --index-filter 'git rm --cached --ignore-unmatch big_file1' HEAD~8..HEAD
$ git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch big_file2' HEAD~8..HEAD

核武器级选项:filter-branch

有另一个历史改写的选项,如果想要通过脚本的方式改写大量提交的话可以使用它——例如,全局修改你的邮箱地址或从每一个提交中移除一个文件。 这个命令是 filter-branch,它可以改写历史中大量的提交,除非你的项目还没有公开并且其他人没有基于要改写的工作的提交做的工作,否则你不应当使用它。 然而,它可以很有用。 你将会学习到几个常用的用途,这样就得到了它适合使用地方的想法。

Caution git filter-branch 有很多陷阱,不再推荐使用它来重写历史。 请考虑使用 git-filter-repo,它是一个 Python 脚本,相比大多数使用 filter-branch 的应用来说,它做得要更好。它的文档和源码可访问 https://github.com/newren/git-filter-repo 获取。

从每一个提交中移除一个文件

这经常发生。 有人粗心地通过 git add . 提交了一个巨大的二进制文件,你想要从所有地方删除。 可能偶然地提交了一个包括一个密码的文件,然而你想要开源项目。 filter-branch 是一个可能会用来擦洗整个提交历史的工具。 为了从整个提交历史中移除一个叫做 passwords.txt 的文件,可以使用 --tree-filter 选项给 filter-branch

1
2
3
$ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD
Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21)
Ref 'refs/heads/master' was rewritten

--tree-filter 选项在检出项目的每一个提交后运行指定的命令然后重新提交结果。 在本例中,你从每一个快照中移除了一个叫作 passwords.txt 的文件,无论它是否存在。 如果想要移除所有偶然提交的编辑器备份文件,可以运行类似 git filter-branch --tree-filter 'rm -f *~' HEAD 的命令。

最后将可以看到 Git 重写树与提交然后移动分支指针。 通常一个好的想法是在一个测试分支中做这件事,然后当你决定最终结果是真正想要的,可以硬重置 master 分支。 为了让 filter-branch 在所有分支上运行,可以给命令传递 --all 选项。

使一个子目录做为新的根目录

假设已经从另一个源代码控制系统中导入,并且有几个没意义的子目录(trunktags 等等)。 如果想要让 trunk 子目录作为每一个提交的新的项目根目录,filter-branch 也可以帮助你那么做:

1
2
3
$ git filter-branch --subdirectory-filter trunk HEAD
Rewrite 856f0bf61e41a27326cdae8f09fe708d679f596f (12/12)
Ref 'refs/heads/master' was rewritten

现在新项目根目录是 trunk 子目录了。 Git 会自动移除所有不影响子目录的提交。

全局修改邮箱地址

另一个常见的情形是在你开始工作时忘记运行 git config 来设置你的名字与邮箱地址, 或者你想要开源一个项目并且修改所有你的工作邮箱地址为你的个人邮箱地址。 任何情形下,你也可以通过 filter-branch 来一次性修改多个提交中的邮箱地址。 需要小心的是只修改你自己的邮箱地址,所以你使用 --commit-filter

1
2
3
4
5
6
7
8
9
$ git filter-branch --commit-filter '
if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ];
then
GIT_AUTHOR_NAME="Scott Chacon";
GIT_AUTHOR_EMAIL="schacon@example.com";
git commit-tree "$@";
else
git commit-tree "$@";
fi' HEAD

这会遍历并重写每一个提交来包含你的新邮箱地址。 因为提交包含了它们父提交的 SHA-1 校验和,这个命令会修改你的历史中的每一个提交的 SHA-1 校验和, 而不仅仅只是那些匹配邮箱地址的提交。

How to install Intel IPP on Ubuntu

I wanted to try Intel Integrated Performance Primitives (IPP) with OpenCV. I installed IPP with these steps:

Intel IPP can be downloaded from here. If you are using it for non-commercial purposes, you can get it for free through Intel’s Non-Commercial Software Development webpage. You need to register with an email address. You will be sent an email with the download link and a registration key.

Download the Intel IPP version you want, beware that its a huge download. I downloaded Intel IPP 7.1, which ships as a 777MB .tgz file.

Unzip the downloaded .tgz file. Run the install.sh file. You will be asked to enter your registration key.

The installer walks you through the steps of installing IPP. I was asked to install the gcc-multilib package, before I could proceed. So, I did:

1
$ sudo apt-get install gcc-multilib

By default, the IPP files are installed to /opt/intel/

Going by the steps given on the Intel website, you are supposed to run the ippvars.sh script, which is in the /opt/intel/ipp/bin directory. It sets the following environment variables: IPPROOT, LIBRARY_PATH and LD_LIBRARY_PATH. This script failed to work for me. So, I set those manually in my .bashrc:

1
2
3
4
# My .bashrc
export IPPROOT=/opt/intel/composer_xe_2013.1.117/ipp
export LIBRARY_PATH=$LIBRARY_PATH:/opt/intel/composer_xe_2013.1.117/ipp/lib/intel64:/opt/intel/composer_xe_2013.1.117/compiler/lib/intel64
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/intel/composer_xe_2013.1.117/ipp/lib/intel64:/opt/intel/composer_xe_2013.1.117/compiler/lib/intel64

linux后台执行命令:&和nohup

当我们在终端或控制台工作的时候,如果希望同时进行另外一个工作,那么此时就希望将当前的工作放在后台运行,特别是如果当前的命令执行时间会很长的情况下。

那么下面就说下两种方法。

&

命令后面加上&相信很多人都用过,比较适合一些费时的命令或脚本,不过注意不要讲有交互的命令放在后台执行,因为这样你的机器就会一直等待输入。使用方法为

1
$ command &

如果放在后台的作业会产生大量的输出,那么此时最好可以将输出重定向到某个文件中,使用方法为

1
$ command > out.file 2>&1 &

其中2>&1 表示将标准出错重定向到标准输出

不过使用&有的弊端,就是一旦把当前的控制台关掉或者账号退出时就会停止作业。

此时就需要下面的这个命令了。

nohup

nohup命令可以在退出账户后继续执行相应的命令,意思为不挂起no hang up。

命令的使用方法如下:

1
$ nohup command &

默认情况下作业的所有输出被重定向到一个nohup.out文件中,也可以指定输出文件,如下所示:

1
$ nohup command > mynohup.file 2>&1 &

不过这里还是有需要注意的事项,非正常退出可能会导致命令失效,所以需要使用exit正常退出当前账户。