编程规范
PEP8
- 官方版:styleguide | Style guides for Google-originated open-source projects
- 中文版:Python 风格指南 - 内容目录 — Google 开源项目风格指南
语言特性
三元运算符
1
2
#如果条件为真,返回真 否则返回假
condition_is_true if condition else condition_is_false
例如:
1
2
is_fat = True
state = "fat" if is_fat else "not fat"
强制类型转换
如将 3.5 强制转换为 3:
1
2
>>> int(3.5)
3
Python 中常用的类型转换的函数有:
int(x)
: 将 x 转换为一个整数float(x)
: 将 x 转换到一个浮点数str(x)
: 将对象 x 转换为字符串tuple(s)
: 将序列 s 转换为一个元组list(s)
: 将序列 s 转换为一个列表set(s)
: 将序列 s 转换为一个集合
格式化字符串
本节包含
str.format()
语法的示例以及与旧式%
格式化的比较。该语法在大多数情况下与旧式的
%
格式化类似,只是增加了{}
和:
来取代%
。例如,,'%03.2f'
可以被改写为'{:03.2f}'
。新的格式语法还支持新增的不同选项,将在以下示例中说明。
按位置访问参数:
1 2 3 4 5 6 7 8 9 10 11 >>> >>> '{0}, {1}, {2}'.format('a', 'b', 'c') 'a, b, c' >>> '{}, {}, {}'.format('a', 'b', 'c') # 3.1+ only 'a, b, c' >>> '{2}, {1}, {0}'.format('a', 'b', 'c') 'c, b, a' >>> '{2}, {1}, {0}'.format(*'abc') # unpacking argument sequence 'c, b, a' >>> '{0}{1}{0}'.format('abra', 'cad') # arguments' indices can be repeated 'abracadabra'按名称访问参数:
1 2 3 4 5 6 >>> >>> 'Coordinates: {latitude}, {longitude}'.format(latitude='37.24N', longitude='-115.81W') 'Coordinates: 37.24N, -115.81W' >>> coord = {'latitude': '37.24N', 'longitude': '-115.81W'} >>> 'Coordinates: {latitude}, {longitude}'.format(**coord) 'Coordinates: 37.24N, -115.81W'访问参数的属性:
1 2 3 4 5 6 7 8 9 10 11 12 13 >>> >>> c = 3-5j >>> ('The complex number {0} is formed from the real part {0.real} ' ... 'and the imaginary part {0.imag}.').format(c) 'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.' >>> class Point: ... def __init__(self, x, y): ... self.x, self.y = x, y ... def __str__(self): ... return 'Point({self.x}, {self.y})'.format(self=self) ... >>> str(Point(4, 2)) 'Point(4, 2)'访问参数的项:
1 2 3 4 >>> >>> coord = (3, 5) >>> 'X: {0[0]}; Y: {0[1]}'.format(coord) 'X: 3; Y: 5'替代 %s 和 %r:
1 2 3 >>> >>> "repr() shows quotes: {!r}; str() doesn't: {!s}".format('test1', 'test2') "repr() shows quotes: 'test1'; str() doesn't: test2"对齐文本以及指定宽度:
1 2 3 4 5 6 7 8 9 >>> >>> '{:<30}'.format('left aligned') 'left aligned ' >>> '{:>30}'.format('right aligned') ' right aligned' >>> '{:^30}'.format('centered') ' centered ' >>> '{:*^30}'.format('centered') # use '*' as a fill char '***********centered***********'替代 %+f, %-f 和 % f 以及指定正负号:
1 2 3 4 5 6 7 >>> >>> '{:+f}; {:+f}'.format(3.14, -3.14) # show it always '+3.140000; -3.140000' >>> '{: f}; {: f}'.format(3.14, -3.14) # show a space for positive numbers ' 3.140000; -3.140000' >>> '{:-f}; {:-f}'.format(3.14, -3.14) # show only the minus -- same as '{:f}; {:f}' '3.140000; -3.140000'替代 %x 和 %o 以及转换基于不同进位制的值:
1 2 3 4 5 6 7 >>> >>> # format also supports binary numbers >>> "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42) 'int: 42; hex: 2a; oct: 52; bin: 101010' >>> # with 0x, 0o, or 0b as prefix: >>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42) 'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010'使用逗号作为千位分隔符:
1 2 3 >>> >>> '{:,}'.format(1234567890) '1,234,567,890'表示为百分数:
1 2 3 4 5 >>> >>> points = 19 >>> total = 22 >>> 'Correct answers: {:.2%}'.format(points/total) 'Correct answers: 86.36%'使用特定类型的专属格式化:
1 2 3 4 5 >>> >>> import datetime >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58) >>> '{:%Y-%m-%d %H:%M:%S}'.format(d) '2010-07-04 12:15:58'嵌套参数以及更复杂的示例:
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 >>> >>> for align, text in zip('<^>', ['left', 'center', 'right']): ... '{0:{fill}{align}16}'.format(text, fill=align, align=align) ... 'left<<<<<<<<<<<<' '^^^^^center^^^^^' '>>>>>>>>>>>right' >>> >>> octets = [192, 168, 0, 1] >>> '{:02X}{:02X}{:02X}{:02X}'.format(*octets) 'C0A80001' >>> int(_, 16) 3232235521 >>> >>> width = 5 >>> for num in range(5,12): ... for base in 'dXob': ... print('{0:{width}{base}}'.format(num, base=base, width=width), end=' ') ... print() ... 5 5 5 101 6 6 6 110 7 7 7 111 8 8 10 1000 9 9 11 1001 10 A 12 1010 11 B 13 1011
pip
pip 是 Python 的包管理工具,类似于 Ubuntu 中的 apt,CentOS 中的 yum
。
index-url
Python 包默认的源在国外,下载很慢,因此建议切换到国内源,如清华的。
- 临时修改:使用
-i
参数(--index-url
)。例如:1
$ pip install --index-url https://pypi.tuna.tsinghua.edu.cn/simple/ SomePackage
- 永久修改:修改
%APPDATA%\pip\pip.ini
内容如下(以 Windows 为例,其它平台的配置文件的位置参见 https://pip.pypa.io/en/stable/user_guide/#config-file ):1 2 3
[global] timeout = 60 index-url = https://pypi.tuna.tsinghua.edu.cn/simple/
常用国内源:
- 阿里云: http://mirrors.aliyun.com/pypi/simple/
- 中国科技大学: https://pypi.mirrors.ustc.edu.cn/simple/
- 豆瓣(douban): http://pypi.douban.com/simple/
- 清华大学: https://pypi.tuna.tsinghua.edu.cn/simple/
- 中国科学技术大学: http://pypi.mirrors.ustc.edu.cn/simple/
详情可参考 https://yq.aliyun.com/articles/652884
virtualenv
建议使用 virtualenv
以避免将系统的 Python 库弄乱。
下面简单介绍virtualenv
的安装与使用(以 Windows 平台为例)。这里使用 Powershell,事实上更推荐微软最新开发的跨平台的 powershell。CMD 亲测不可行,在.\venv\Scripts\activate
这一步会失败,虽然看起来成功了。
- 切换下载源:默认的源在国外,下载很慢,因此建议切换到国内源,如清华的。Windows 中编辑
%APPDATA%\pip\pip.ini
文件如下即可(没有该文件及父目录就手动创建):1 2 3
[global] timeout = 60 index-url = https://pypi.tuna.tsinghua.edu.cn/simple
- 安装
virtualenv
:1
pip3 install virtualenv
- 在当前目录创建一个
virtualenv
环境(环境信息保存在.\venv
文件夹中):1
virtualenv venv
- 进入该环境:
1
.\venv\Scripts\activate
- 安装依赖(包会放在
.\venv
中):1
pip3 install -r requirements.txt
- 运行脚本(会使用当前环境中的 Python):
1
python3 main.py
日志
参见 logging — Logging facility for Python — Python 3.7.4 documentation
注意其中给出的三个链接:
其它常用的链接:
format
参考手册:logging — Logging facility for Python — Python 3.7.4 documentationdatefmt
参考手册:time — Time access and conversions — Python 3.7.4 documentation
常见用法
简单使用
1
2
3
4
5
6
7
import logging
logging.basicConfig(filename='example.log', filemode='w', format='[%(asctime)s]-[%(name)s](%(filename)s:%(lineno)d)-[%(levelname)s]>>> %(message)s', datefmt='%Y-%m-%d %H:%M:%S',level=logging.DEBUG)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')
logging.error('And this, too too')
配置文件
1
2
3
4
5
6
7
8
9
10
11
12
import logging
import logging.config
import logging.handlers
import yaml
def prepare():
logging.config.dictConfig(yaml.safe_load(open("conf/logging.yaml", "r")))
global logger
logger = logging.getLogger("dream")
logger.info("logger.handlers: %s", logger.handlers)
...
其中conf/logging.yaml
:
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
version: 1
formatters:
brief:
format: "%(funcName)s(%(lineno)d):%(levelname)s: %(message)s"
precise:
format: "[%(asctime)s]-[%(name)s](%(filename)s:%(lineno)d)-[%(levelname)s]>>> %(message)s"
handlers:
console:
class: logging.StreamHandler
level: INFO
formatter: brief
stream: ext://sys.stdout
file:
class: logging.handlers.RotatingFileHandler
level: DEBUG
formatter: precise
filename: logs/main.log
mode: a
encoding: "utf-8"
maxBytes: 4194304
backupCount: 2
loggers:
dream:
level: DEBUG
handlers: [file,console]
propagate: no
root:
level: DEBUG
handlers: [console]
调试
(温馨提示:本部分使用的 Python 版本为 Python2.7)
详情参考: IBM-Python 代码调试技巧
使用 pdb
在.bashrc
文件中定义函数pdb
,方便使用:
1
2
3
function pdb(){
python -m pdb $1
}
使用方法:
1
pdb test.py
常用命令:
命令 | 解释 |
---|---|
break 或 b 设置断点 | 设置断点 |
continue 或 c | 继续执行程序 |
list 或 l | 查看当前行的代码段 |
step 或 s | 进入函数 |
return 或 r | 执行代码直到从当前函数返回 |
exit 或 q | 中止并退出 |
next 或 n | 执行下一行 |
pp | 打印变量的值 |
help | 帮助 |
详情参考: 26.2. pdb — The Python Debugger
IDE
PyCharm
Python2 vs Python3
遇到过的问题
- python - Check if multiple strings exist in another string - Stack Overflow
- Read JSON file using Python - GeeksforGeeks
- How do you read a file into a list in Python? - Stack Overflow
- Comparing two paths in python - Stack Overflow
- Python os.chdir() method - GeeksforGeeks
-
[Making Use of Environment Variables in Python Nylas](https://www.nylas.com/blog/making-use-of-environment-variables-in-python/) - get working directory in python - Stefaan Lippens inserts content here
- python 两个list 求交集,并集,差集_bitcarmanlee的博客-CSDN博客_python 两个列表求差集
- python - How do I write JSON data to a file? - Stack Overflow
- Writing a list to a file with Python - Stack Overflow
- python - How to execute a program or call a system command? - Stack Overflow
- python - How to retrieve an element from a set without removing it? - Stack Overflow
How to get an absolute file path?
1
2
3
>>> import os
>>> os.path.abspath("mydir/myfile.txt")
'C:/example/cwd/mydir/myfile.txt'
详情参见 https://stackoverflow.com/a/51523
捕获 CTRL+C 信号?
(温馨提示:本部分使用的 Python 版本为 Python2.7)
-
使用 python 的异常
KeyboardInterrupt
:1 2 3 4 5 6 7 8 9 10 11 12 13 14
import time import sys import signal signal.signal(signal.SIGINT, signal.default_int_handler) x = 1 try: while True: print x time.sleep(.3) x += 1 except KeyboardInterrupt: print "Bye" sys.exit()
-
使用
signal
模块1 2 3 4 5 6 7 8 9
#!/usr/bin/env python import signal import sys def signal_handler(sig, frame): print('You pressed Ctrl+C!') sys.exit(0) signal.signal(signal.SIGINT, signal_handler) print('Press Ctrl+C') signal.pause()
详情参考: How do I capture SIGINT in Python?
UnicodeEncodeError?
(温馨提示:本部分使用的 Python 版本为 Python2.7)
执行代码:
1
2
3
4
5
6
def save_html(content):
with open('a.html', 'w') as f:
f.write(content)
r=requests.get('https://www.baidu.com')
save_html(r.text)
报错:
1
2
3
4
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in save_html
UnicodeEncodeError: 'ascii' codec can't encode characters in position 317-343: ordinal not in range(128)
解决办法:在使用前先调用encode
函数将其编码为相应的编码(通常为UTF8
)即可。如下所示
1
2
3
4
def save_html(content):
with open('a.html', 'w') as f:
f.write(content.encode('utf8'))
List user defined variables?
使用dir()
函数然后再过滤即可。例如:
1
2
3
>>> x = 3
>>> set(dir()) - set(dir(__builtins__))
set(['__builtins__', 'x'])
又如:
1
2
3
4
5
6
7
8
9
10
#!/us/bin/python
foo1 = "Hello world"
foo2 = "bar"
foo3 = {"1":"a", "2":"b"}
foo4 = "1+1"
for name in dir():
if not name.startswith('__'):
myvalue = eval(name)
print name, "is", type(myvalue), "and is equal to ", myvalue
详情参见 List user defined variables, python - Stack Overflow
How to read a file line-by-line into a list?
参见python - How to read a file line-by-line into a list? - Stack Overflow
Getting exception details?
参见Getting exception details in Python - Stack Overflow
Trace Python imports?
使用-v
参数:
1
python -v -m /usr/lib/python2.6/timeit.py
详情参见 debugging - Trace Python imports - Stack Overflow
参考资料
- How do I capture SIGINT in Python?
- UnicodeEncodeError: ‘ascii’ codec can’t encode character u’\xa0’ in position 20: ordinal not in range(128)