Python FAQ - zhongjiajie/zhongjiajie.github.com GitHub Wiki
- 交互式控制台: Python相比静态语言最大的特点是有一个交互式控制台(REPL)(read-eval-print loop,读取、求值、输出的循环)
- 直接使用python关键字进入终端设备(tty)
-
python -c command [arg] ...
: 将-c
后面的代码交给python解释器运行 -
python -m module [arg] ...
: 将python中的部分模块按照指定的参数运行
- 内置方法,查看某个模块的属性和方法
dir(sys)
,查看方法的详情help(sys)
双下划线(dunder)
-
_var
: 单前导下划线 -
var_
: 单末尾下划线 -
__var
: 双前导下划线 -
__var__
: 双前导和末尾下划线 -
_
: 单下划线
SO-How do I check if a variable exists
# To check the existence of a local variable
if 'myVar' in locals():
# myVar exists.
# To check the existence of a global variable
if 'myVar' in globals():
# myVar exists.
# To check if an object has an attribute:
if hasattr(obj, 'attr_name'):
# obj.attr_name exists.
检测 Pyhton 版本,py2还是py3
import sys
if sys.version_info[0] < 3:
print('python version is 2')
else:
print('python version is 3)
PY3 = sys.version_info[0] == 3
if PY3:
<py3 part>
else:
<py2 part>
- 将10进制的20转成获取3进制:
int('20', base=3)
结果是6, 相当于20 / 10 * 3 = 6
如果使用zsh安装第三方包,包名中有[]
的话要使用引号引用pip install 'requests[security]'
python3中纯粹的int类型没有没有界限,但是机器的最大值是有界限的,可以通过sys.maxsize
,如果是python2的话则是sys.maxint
-
in
与not in
判断元素是否在序列里面 -
is
与is not
判断是否同一个对象 - 较为复杂的判断
a < b == c
,等同于(a < b) and (b == c)
-
and or not
连接判断条件,整体优先级小于比较运算符.优先级not > and > or
,所以A and not B or C
等同于(A and (not B)) or C
-
and or
又称为短路运算符,and中只要有一个是false后面的就不会执行,or中只要有一个是true后面的就不执行
-
- 遍历字典内容:
for k, v in d.items()
- 遍历序列:
for i in sequence
,sequence包括list及set - 带序号遍历序列:
for i, v in enumerate(sequence)
,sequence包括list和set - 同时遍历两个或以上的序列(相同索引号循环):
for s1, s2 in zip(sequence1, sequence2)
- 遍历嵌套列表:
l = [['10', '20'], ['30', '40', '50', '20', '20', '30', '20']]; [[float(y) for y in x] for x in l]
两个相同类型的序列才可以比较,比较的时候是将先比较两个序列的第一个元素,如果相等则比较两个序列的下一个元素.下面的全是true
-
(1, 2, 3) < (1, 2, 4)
及[1, 2, 3] < [1, 2, 4]
(1, 2, 3, 4) < (1, 2, 4)
(1, 2) < (1, 2, -1)
(1, 2, 3) == (1.0, 2.0, 3.0)
python运行shell或者cmd命令
- 通过
os.system
模块
import os
bash_commnad = 'ls -al'
os.system(bash_command)
- 推荐用法:通过
subprocess
模块,参考Calling an external command in Python
import subprocess
p = subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
# 处理命令的输出
for line in p.stdout.readlines():
print line,
retval = p.wait()
import errno
import shutil
from tempfile import mkdtemp
from contextlib import contextmanager
@contextmanager
def TemporaryDirectory(suffix='', prefix=None, dir=None):
name = mkdtemp(suffix=suffix, prefix=prefix, dir=dir)
try:
yield name
finally:
try:
shutil.rmtree(name)
except OSError as e:
# ENOENT - no such file or directory
if e.errno != errno.ENOENT:
raise e
from tempfile import NamedTemporaryFile
tmpfile = NamedTemporaryFile()
# append
with open(tmpfile.name, 'a') as f:
f.write("test content")
# write
with open(tmpfile.name, 'w') as f:
f.write("context")
# read
with opne(tmpfile.name) as f:
for line in f:
# do something to f
# 单行代码完成统计,内存较为友好
num_lines = sum(1 for line in open(file_path) if line.rstrip())
# 如果要做得更好,比如open完了之后close文件,如果文件不能打开报错等
try:
with open(file_path, 'r') as r:
num = sum(1 for _ in r)
execpt IOError:
raise IOError()
# 通过命令行调用shell完成,这个会比纯python快,但是牺牲了内存
import subprocess
def count_file_lines(file_path):
sp_output = subprocess.check_output(['wc', '-l', file_path])
return sp_output.split(' ')[0]
Make python enter password when running a csh script: 在需要输入密码的时候输入
import getpass
pswd = getpass.getpass('Password:')
经常用来作为工具的代码块
启动简单的HTTP服务用于访问指定位置的资源
# python 2
python2 -m SimpleHTTPSerer
# python 3
python3 -m http.server
- 函数参数传递: Python所有的变量都可以理解是内存中一个对象的“引用”,参见这里
- “可更改”(mutable): strings, tuples, numbers
- “不可更改”(immutable): list, dict, set
# -*- coding: utf-8 -*-
是python2时代的产物,python3中默认已经是UTF-8编码了,所以并不需要,详情。使用pre-commit
中fix-encoding-pragma可以对相关内容进行修改。但是更加好的方式是使用pyupgrade配合pre-commit使用。
unicode在python2中才有,到了py3中就统一成了str类型了
The difference is: open takes a file name (and some other arguments like mode or encoding), io.StringIO takes a plain string and both return file-like objects.
- Use open to read files ;
- Use StringIO when you need a file-like object and you want to pass the content of a string.
if x is not None
应该是更加被推崇的写法,应该这个更加明确,为了判断参数是否为空,参考
del a[index]
和a.remove(k)
是否在循环内外都是同一表现,for k in a
通过记住上一个index值来判断下一个值
In [1]: a = [1,2,3,4,5]
...: i = 0
...: for k in a:
...: del a[i]
...: print(k)
...: print(a)
...: i = i+1
...:
1
[2, 3, 4, 5]
3
[2, 4, 5]
5
[2, 4]
In [2]: a = [1,2,3,4,5]
...: for k in a:
...: a.remove(k)
...: print(k)
...: print(a)
...:
1
[2, 3, 4, 5]
3
[2, 4, 5]
5
[2, 4]
在使用python进行一个日志分析工具的编写过程中,由于日志很大,大约为30M。在读写操作的时候,遇到完全读取到内存中,导致cpu内存不停攀升,脚本无法继续运行的问题。有没有好的方法来处理这样的单个大的文件?
python解析XML文件时,可以使用的办法有minidom、ElementTree和SAX,其中minidom和elementTree都是同一种思路,即将XML文件作为一个Tree,在解析之前,将所有节点读入内存,并保存它们之间的父子结构关系,使用这种方法来解析XML文件的优势在于可以简单地获取到节点之间的关系,可以快速地获取某个节点,最大的劣势就在于当文件很大时,解析的速度会成快速地降低,可以想象如果需要将几十M甚至上百M的数据读入内存并将节点组装成一棵树,需要极大的运算量和内存空间。
针对这点,XML提供了另外一种解析思路,即基于事件驱动的机制(SAX)。解析时解析器会响应的点就在于消息,比如某个标签(如<table>
)开始,和某个标签(如</table>
)结束,当事件发生时,解析器会调用我们预先编写好的程序段去响应。Python的SAX机制包括解析器和事件处理器。解析器负责读取XML文档,并向事件处理器发送事件,如元素开始跟元素结束事件;而事件处理器则负责对事件作出相应,对传递的XML数据进行处理。