笨办法学python笔记
一篇之前学习Python的笔记,感谢《笨办法学Python》的作者。本文是结合《笨办法学Python》和Python3.3的一些补充。
Ex01
print
后要加括号(python3.3)
Ex02
#
号起注释作用
Ex03
- 整型运算结果一般为整型,除法结果则为浮点型
Ex04
print
参数连接打印时,自动插入空格
Ex05
print
中多个参数格式化时,参数以元组形式传入
Ex06
%r
格式化方式取的是参数的原始数据,字符串参数自动增加单引号或双引号
Ex10
%r
用作debug,%s
用作显示- 反斜杆
\
用作转义,斜杆/
没有意义 '''
(三个单引)与"""
(三个双引)作用一致
Ex11
- 3.3中,
input()
已经替换掉raw_input()
- 3.3中,
print()
输出不换行,需要加第二参数end=''
(双单引号)
Ex16
- 文件操作可能用到的方法:
open
,read
,truncate
,readline
,write(buff)
,close
open
打开文件方式:
'r'
:默认打开方式,只读'w'
:先清空文件,只写'x'
:新建一个文件,只写。已存在文件会报错'a'
:追加,在已有文件后进行写操作。只写'b'
:二进制模式't'
:文本模式'+'
:权限升级,拥有读和写操作。但必须至少有'w''r''x''a'
其中一项
Ex18
- 使用
def
建立函数 - 函数名由字母,数字和下划线
_
组成,但数字不能首位 - 定义或使用函数时必须带括号,定义时参数可有可无,但使用时必须按照定义时的参数进行配置。参数以逗号隔开
- 定义函数后要加上冒号才能进入函数体
- 函数体要向由缩进4个空格字符,结束函数体时要取消缩进
- 运行函数(
run
)、调用函数(call
)、和 使用函数(use
)是同一个意思
Ex19
int()
可以强制转换字符串为整型
Ex24
- 函数可以返回多个结果组成的元组
Ex25
- 通过
import
可以加载py后缀的文件(模块),从而通过.
调用模块中定义的函数 - 在定义函数后第一行中设置
"""xxx"""
的注释,可用于help()
查询
Ex27
- 逻辑运算符
and
与or
或not
非!=
不等于==
等于>=
大于等于<=
小于等于True
真False
假
Ex30
- 只要一行以冒号
:
结尾,它接下来的内容就应该有缩进 - 4个空格的缩进表示新的代码区段创建
Ex32
range()
会产生一个range
对象,可迭代。range
函数会从第一个数到最后一个,但不包含最后一个数字。range(0,5)
就是一个带有0,1,2,3,4
的range
对象- for-loop的格式是
for xxx in yyy:
其中yyy
是可迭代对象 - 列表
list
有以下方法:
append
:追加,可理解成在最后位置插入clear
:清空,清除所有列表内容copy
:复制,复制一个列表副本(新的内存)count
:数目,列表元素个数extend
:扩展,可以从别的可迭代对象中获取元素扩展自身列表index
:索引,列表元素索引insert
:插入,根据 给定的位置进行插入元素pop
:提取,会从列表中删除指定位置元素,调用时会返回该元素。没有参数时默认后进先出remove
:移除,删除第一次出现该值的元素reverse
:倒序,对列表进行倒序处理sort
:排序,对序列进行排序
Ex33
- 尽量少用while-loop,大部分时候for-loop是更好的选择
- 重复检查你的
while
语句,确定你测试的布尔表达式最终会变成False
- while-loop的格式为
while xxx :
当满足xxx
为True
时开始,xxx
为False
时停止
Ex37
- 关键字学习
and
:逻辑运算符,与del
:删除变量,包括命名和值from
:加载模块使用,与import
一起,从xxx
导入yyy
not
:逻辑运算符,非while
:while-loop核心,True
时运行循环体,False
时退出循环as
:别名,指向。如在import
后时,用作导入模块的别名;用在with
后时,可以指代with
后的with_item,并在with
内部使用elif
:否则如果,if
语句的带条件分支。global
:定义全局变量or
:逻辑运算符,或with
:通过把xxx
替换为yyy
,执行下面的代码assert
:测试用,测试表达式1,如果为False
,抛出异常并执行表达式2else
:否则,if
语句的不带条件分支,后不能再接if
的分支if
:条件语句pass
:空语句,跳过,保持结构完整性yield
:量产,可以根据控制生产结果。带有yield
的函数为生成器,每次调用到yield
停止,再次调用会从上次结束的地方,保持上次的状态执行到yield
关键字break
:跳出循环except
:与try
一起用,捕获异常,进行异常处理import
:加载模块,使外部模块可以调用class
:类,定义类in
:如果xxx
在yyy
中,则xxx in yyy
返回True
。可以与for
一起做for-loopraise
:强制抛出一个异常continue
:跳出本次循环并进行下一次循环finally
:在try
块后引用,无论是否出现异常,总会执行finally
块is
:判断两者是否为同一对象,类型相同且值相同时返回True
,否则返回False
return
:返回,在函数中返回值def
:定义函数for
:for-loop使用,与in
一起lambda
:匿名函数try
:用于异常处理,放在函数执行前,配合except
从句和finally
块使用nonlocal
:用于闭包内修改外部变量。如果不定义nonlocal
,闭包内只能读外部变量,而不能修改(非全局变量)None
:常量,空值,数据类型为NoneType
,与非None
值比较总返回False
True
:布尔值,真False
:布尔值,假
- 字符串格式化
print("The format is %* " % arg)
*替换以下格式
%d
,%i
:带符号的十进制整数%o
:不带符号的八进制%u
:不带符号的十进制%x
:不带符号的十六进制(小写)%X
:不带符号的十六进制(大写)%e
:科学计数法的浮点数(小写)%E
:科学计数法的浮点数(大写)%f
,%F
:十进制浮点数%g
:如果指数大于-4或者小于精度值则和e相同,否则和f相同%G
:如果指数大于-4或者小于精度值则和E相同,否则和F相同%c
:单字符(接受整数或者单字符字符串)%r
:字符串(使用repr
转换任意Python对象)%s
:字符串(使用str
转换任意Python对象)
- 操作符号
+
:加法,正则中可匹配1个或多个字符-
:减法,负号,正则中可连接一个字符范围*
:乘法,正则中可匹配0个或多个字符;收集其余的位置参数**
:幂运算;收集关键字参数/
:除法//
:除法,结果向下取整%
:取余<
:小于>
:大于<=
:小于等于>=
:大于等于==
:等于,相等返回True
!=
:不等于()
:运算中的优先计算;函数定义或调用时包含参数;正则中用于分组;定义元组[]
:定义列表;序列中放置索引;正则中的范围单字符{}
:定义字典;正则中用于指定重复次数@
:修饰符,包装函数(需要深入一下),
:分隔参数:
:开始新的代码块;索引集省略中间索引;键值对分隔.
:子模块,对象属性=
:赋值;
:表达式结束+=
:加值符-=
:减值符*=
:乘值符/=
:除值符//=
:除值符,结果向下取整%=
:余值符**=
:幂值符
Ex38
- 列表的索引可以使用负值,相当于倒序取值
'xxx'.join(列表)
可以用xxx
连接列表每项- Python的面向对象方法可理解成,以自身作为其中一个参数的函数调用
Ex39
- 字典的方法
clear()
:清空字典中所有元素copy()
:复制,复制一个字典副本(新的内存)dict.fromkeys(S [,v])
:这个是dict类型的方法,用于构造新字典。如果S
可迭代,则迭代S
的值作为key
,对应的值为v
。v
没填默认为None
get(k[,d])
:取值,如果字典中k
键存在,则取k
对应的值;否则,有d
参数取d
,没设d
默认为None
items()
:字典元素的集合(键值对集)keys()
:字典键的集合pop(k[,d])
:提取,如果k
键存在,则取k
对应的值;否则,有d
参数取d
,没设d
默认为None
popitem()
:提取键值对,后进先出setdefault(k[,d])
:执行get(k[,d])
,如果k
键不存在,把k
键的值设为d
values()
:值的集合
Ex40
- 类的定义
class Xxx(object):
,意思为定义继承object
的Xxx
类型,需定义一个__init__(self[, values])
函数作为初始化(或pass
)
Ex41
- 一些词汇
class
:定义类的关键字。告诉Python创建新类型object
:对象。最基本类型instance
:实例。Python除元类外,都是某个类的实例def
:定义类里边函数关键字self
:对自身的调用。class
里的函数都会有这个参数,指代被访问的object
或instance
的一个变量inheritance
:继承。指一个class
可以继承另一个类的特性,和父子关系类似composition
:构建。指一个class
可以作为另一个类的部件构建起来,像车子和车轮的关系attribute
:属性。class
的一个属性,来自composition
,通常是一个变量is-a
:用来描述一个继承关系,如Salmon is-a Fish
,三文鱼是一种鱼has-a
:描述一种东西是另外一些东西组成,或是有某个特征,Salmon has-a mouth
,三文鱼有嘴(这个特征)
Ex42
- Python中的一切都是对象,要么是类的实例,要么是元类的实例,除了
type
Ex43
- 在函数的结束时返回函数名,加上括号就可以调用了
getattr()
从某个对象中取出某个属性
Ex44
super(本类名,self)
允许子类中调用父类的方法或属性。多重继承时,如果调用父类方法时,方法在在多个父类中重复,Python会有算法判断该用那个父类的方法- 合成有别于继承,把类的属性实例化为要合成的对象,譬如
self.name = Name()
,这时,就可以通过调用self.name
使用Name
类中的方法了 - 编码规范
编码布局
- 缩进
- 使用4空格进行分块缩进
- 不要空格与制表符混合使用,要么全是空格,要么全是制表符
- 分行
- 单行最大长度为79字符,推荐最大为72字符
- 长行需要拆分显示,拆分行时在运算符后进行拆分
- 续行使用8空格制表符(tab)
- 空行
- 分隔独立函数与类定义用双空行
- 类中的方法定义之间分隔使用单空行
- 使用空行分隔一些有关联的定义或函数
- 使用空行划分逻辑块
- 字符集
- Python 2.x发行版编译时使用ASCII或Latin-1编码,3.0以上都是使用UTF-8
- 标识符(命名)必须使用ASCII,应该使用易读的英文
- 字符串文字和注释都必须使用ASCII
- 但对于中文注释,需要在开始处插入
# -*- coding: utf-8 -*-
,字符串还需要转换成utf-8编码
- 加载
- 加载模块时应该分行加载,不应该
import xxx, yyy
- 加载单一模块中的子模块时,可以使用逗号分隔子模块,
from xxx import xxx, yyy
- 加载总是放在文件开始处,在模块注释文档后,在定义全局变量和模块内容前
- 加载包括标准类库,关联的第三方类库,本地特有的应用或类库
- 在多组加载之间使用空行分隔
- 不推荐使用相对路径加载内置包,要使用绝对包路径加载
- 如果
xxx
中包含yyy
模块,可以import xxx
,在通过xxx.yyy
使用yyy
- 加载模块时应该分行加载,不应该
- 缩进
表达式和语句中的空白
- 多余的
- 紧接中括号、圆括号和大括号内两侧的空白
- 紧接逗号、分号、冒号前的空白
- 紧接函数名与参数左侧括号之间的空白
- 紧接列表名与索引或切片左侧中括号之间的空白
- 在操作符周围填充,是多个操作符对齐的空白
- 其他建议
- 在以下操作符两边加上一个空格:赋值符(
=
)、各种增值符(+=
,-=
等)、判断符(==
,<
,>
,!=
,<>
,<=
,>=
,in
,not is
,is
,is not
)、逻辑符(and
,or
,not
) - 对于运算符,应该在低优先级的运算符两边增加一个空格,如
x*y + z
- 不要在配置函数关键字参数和默认值的等号(=)两边加空格
- 不提倡复合语句,不提倡多条语句写在一行
- 可以在
if
、for
、while
语句的冒号后写一个小语句,但不能写多行语句,更不推荐写成一个长行
- 在以下操作符两边加上一个空格:赋值符(
- 多余的
注释
- 提示
- 错误注释代码比没有注释更糟糕。所以要保持注释更新
- 注释是一句话,格式要跟语言格式一致
- 大段的注释要有标点
- 请用英文写注释,除非120%肯定读代码都懂中文
- 块注释
- 块注释要与紧随的代码有同一缩进级别
- 每一行都要以井号(
#
)和一个空格开始
- 行内注释
- 节制使用行内注释
- 与语句同一行,与语句至少分隔两个空格,以井号(
#
)和一个空格开始 - 行内注释是不必要的,但如果需要特别注意的地方加上行内注释,会非常有用
- 文档字符串
- 为所有公用模块、函数、类和方法写上文档字符串
- 在多行文档字符串结束符
"""
上方增加一个空行 - 单行的话可以把结束符
"""
写在同一行
- 提示
版本纪录维护
* 如果对代码进行了版本维护,需要增加两行。第一行为:__version__ = "Reversion: xxxxxxxx $"
第二行为:# $Source$
这两句放在模块文档字符串后所有代码前,并且前后各添加一个空行命名惯例
- 描述性:命名样式
- 通常的样式有:
b
:单小写字母B
:单大写字母lowercase
:小写单词lower_case_with_underscores
:带下划线的小写单词组UPPERCASE
:大写单词UPPER_CASE_WITH_UNDERSCORES
:带下划线的大写单词组CapitalizeWors
:驼峰式(每个单词首字母大写,缩写的每个字母都要大写,如HTTP)mixedCase
:首字母小写的驼峰式Capitalize_Words_With_Underscores
:用下划线连接的驼峰式_single_leading_underscore
:内部私有函数,不能通过from xxx import *
导入single_trailing_underscore_
:用于作为参数时与Python关键字冲突__double_leading_underscore
:命名一个类的属性时,名称会重整。Xxx
类含__yyy
属性,则命名为_Xxx__yyy
- __double_leading_and_trailing_underscore__:用户控制的命名空间里的魔法对象或属性。不能创造这种命名,只能按文档使用
- 通常的样式有:
- 惯例的:命名约定
- 切勿使用
l
(小写L
)、O
(大写o
)、I
(大写i
)作为单字符命名 - 模块使用小写短名,可以使用下划线增强可读性;包名也推荐使用小写短名,但不推荐用下划线
- 类的命名使用驼峰式。只供内部使用的类要加上前置下划线
- 异常命名与类的命名方式类似,如果是错误则需要加上
Error
后缀 - 通过定义
__all__
防止模块输出全局变量,或是在命名前加一个下划线进行内部私有化。把全剧变量当作非公共模块 - 函数定义使用
lower_case_with_underscores
- 总是使用
self
做为实例方法的第一个参数,总是使用cls
作为类方法的第一个参数 - 避免函数命名与关键字冲突的方法是在最后加一个下划线,或者可以使用非关键字的同义词
- 方法名和实例变量的命名与函数命名规则一致,使用
lower_case_with_underscores
;非公共函数使用一个下划线开头;避免与子类的命名冲突,可以使用两个下划线开头,再由Python整合命名 - 常量在模块级别定义,使用
UPPER_CASE_WITH_UNDERSCORES
养成对类方法和实例变量进行私有或公共的分类。如果不能肯定是该公共或是该私有,就先定义为私有的 - 实际上,Python并没有实质的私有概念,因为没有真实存在的私有属性。在开头加个下划线,也只是避免
import
时进行导入,实际通过Xxx._yyy
也是可以使用的
- 切勿使用
- 一些建议:
- 公共方法一律不加前导下划线
- 如果命名与关键字冲突,则添加后缀下划线
- 对于简单的公共数据属性,可以使用@property进行装饰。这个只能在新式类上使用;保持函数行为无副作用,譬如不会影响缓存;不要在计算复杂操作上使用属性装饰,只要很低代价就可以调用这种属性
- 如果在子类继承中,不希望子类继承的属性,可以使用双下划线开头的命名方式;使用命名重整的父类要求简单的命名;命名重整会使调试或取属性魔法函数变得不方便,但命名重整的规则是有文档规范和容易实现的;可以通过改进调用方式,平衡命名重整的使用
- 描述性:命名样式
编程建议
- 用一种不会对Python其他实现(PyPy,Jython,IronPython,Cython,Pysco等)产生消极影响的方式进行编程
- 单一实例的比较不要使用
==
或!=
运算符,应该使用is
或is not
进行比较。如is None
或is not None
if xxx
意思是if xxx is not None
- 如果排序算法含有大量比较时,推荐使用以下六个比较方法:
__eq__
等于,__ne__
不等于,__lt__
小于,__le__
小于等于,__gt__
大于,__ge__
大于等于。实际的比较运算符也是调用了以上方法 - 使用以类为基础的异常。必须继承
Exception
基类,添加文档注释。使用类的命名规则,如果是错误,要加上error
后缀 - 当抛出一个异常时,使用
raise XxxError("yyy")
代替旧格式raise XxxError, "yyy"
- 当捕获一个异常时,如果可以都要把具体的异常写上
except XxxError:
,而不是裸except:
- 裸
except:
可以捕获SystemExit
和KeyboardInterrupt
异常,相当于except BaseException:
。except Exception:
可以捕获所有异常。 - 在以下场景不使用裸
except:
:知道发生了错误,要把错误打印回溯日志;使用try...finally
子句处理raise
抛出的异常 - 在
try:
子句中包含最小量代码,以避免缺陷覆盖 - 当上下文管理器进行不是获取或释放对象资源的调用操作时,需要通过对对象的方法或函数进行调用。
with xxx.yyy(): do(xxx)
而不是with xxx: do(yyy)
- 使用字符串方法代替引用字符串模块。同一操作,字符串方法会比其他字符串处理快很多
- 使用
'xxx'.startswith()
和'xxx'.endswith()
检查字符串前缀和后缀。这样更简洁,更不易出错 - 使用
isinstance()
进行对象类型比较。普通字符串和unicode
字符串可以使用共同基类basestring
- 对于序列(字符串,列表,元组),空队列为
False
。所以不要使用长度为0进行判空,而是直接使用if not xxx:
进行判空 - 字符串后不要加空格,因为一般会看不出来,而且会被一些编辑器删掉
- 不要使用
is
和==
比较布尔值 - Python标准库没有提供函数注释,因为怕形成一种过早的约定和特定的注解样式。建议自行发掘适合自身的注解方式
Ex46
项目框架
projects\
proj_hello\(项目名)
setup.py(安装文件)
NAME\(任意命名)
__init__.py
bin\
docs\
tests\
NAME_test.py
__init__.py
对项目执行测试要在项目名下级执行nosetests
Written with StackEdit.
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!