基础部分
- 当语句以
:
结尾时,后面缩进的语句视为一个代码块 Ture
和False
为布尔值,None
为空值,inf
为无限大- 逻辑运算符为
and
,or
,not
等 //
为地板除法, 结果为整数,%
取余- if中的判断条件若非零、非空字符串、空list,则视为True
- Python中的else if 语法为
elif
- 可以同时赋值
n, a, b = 0, 0, 1
a, b = b, a + b
range(5)
生成0-4的listfor迭代
for name in names:
- 举例:
for x in range(101)
- 字符串也可迭代
for ch in 'ABC'
for x, y in [(1, 1), (2, 4), (3, 9)]
isinstance()
函数判断对象是否是可迭代的
- 举例:
del关键词用于删除,例如:
del list[2]
- 在行末加上续行字符\,可将代码分两行
- 使用固定的随机数种子有助于debug
- 判断类型
type(var)
- 判断函数
type(fn)==types.FunctionType
type(abs)==types.BuiltinFunctionType
type(lambda x: x)==types.LambdaType
type((x for x in range(10)))==types.GeneratorType
- 判断函数
字符串相关
ord()
函数将字符转成数字,chr()
函数将数字转成字符len(str)
计算str的长度
- 也可以计算list中元素的个数
- print相关
- 格式化输出
print('xxx%2d xxx %03d' % (1, 2))
- 如果只有一个占位符 % 后可不用括号
- %%转义普通的%
r''
表示''
中的字符不用转义- print中
''' '''
来表示多行内容 - 连续多个print时,由于python会自动在传入的字符串末尾添加换行符,所以会一行行打印。如果想要打印在一行,就要用:`print(“xxx”,end=”)
- 在一个字符串中传入多个字符串时,会自动用空格分开,如果想要换别的分隔符,就要:
- 格式化输出
print("xx","xxx",sep=',')
print('''line1
line2
line3
line4''')
- 剔除字符串中的空白
开头:str=str.lstrip()
结尾:str=str.rstrip()
两边:str=str.strip()
- 字符串的几个方法
- string.rjust(10,“*”), string.ljust(5,“-”), string.center(8) :
对齐文本 - “想要作为分隔符的字符串”.join([字符串列表])
- [字符串列表]=string.split(“想要作为分隔符的字符串”)
- string.rjust(10,“*”), string.ljust(5,“-”), string.center(8) :
tuple 和 list
list基本操作
- 增加元素
list.append(位置,元素)
- 删除元素
list.pop(位置)
- 不写视为最后一个元素
- list中元素可以类型不同
- 增加元素
Tuple初始化时若只有一个元素,需要加逗号,以免与括号运算混淆:
t=("a",)
Tuple中的元素不能改变,所以比list更加安全,但当Tuple中含有list时,list中的元素却是可以改变的
切片操作
- 从Tuple中取元素时不需要循环,只需要
Tuple[start:end:n]
- n为间隔的个数
- start为第一个元素或者end为最后一个元素时可以省略
- end不取
- [-1]表示list中的最后一个元素
list[-10:]
最后10个数
list[:]
原样复制
- x=string表示x和string指向同一块地址(引用);x=string[:]表示拷贝,指向不同地址
list[::-1]
可以reserve列表- 字符串可以看作list,也可以进行切片操作
- 去除字符串中指定位置的字符,例如第i个
string=string[:i]+string[i+1:]
- 去除字符串中指定位置的字符,例如第i个
- tuple也可以切片
- 从Tuple中取元素时不需要循环,只需要
对于列表、字典等保存可变值来说,变量及引用;对于元组、字符串等不可变值,变量及值
- list.expend(x,y…)可以一次性添加多个元素
在列表中加入字符串时,如果用+=操作,会分开添加一个个字符,用list.append()才能添加整个字符串
list.index(A)
查找值在列表中的位置list.sort(reverse=True)
倒排序(ASCII字符顺序)多重赋值
list=[1,2,3]
a=list[0]
b=list[1]
c=list[2]
可以化简成
list=[1,2.3]
a,b,c=list
注意,左边的变量数必须等于list中的元素个数
- 列表生成器
list(range(1, 11))
- 生成[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[x * x for x in range(1, 11)]
- 生成[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
- 注意加中括号
[x * x for x in range(1, 11) if x % 2 == 0]
- 生成[4, 16, 36, 64, 100]
- 仅有偶数的平方
[m + n for m in 'ABC' for n in 'XYZ']
- 生成[‘AX’, ‘AY’, ‘AZ’, ‘BX’, ‘BY’, ‘BZ’, ‘CX’, ‘CY’, ‘CZ’]
- 两层循环
[k + '=' + v for k, v in d.items()]
- 生成[‘y=B’, ‘x=A’, ‘z=C’]
- 同时迭代多个变量
[s.lower() for s in L]
- 大写全部变小写
字典
- dic的创建
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
- 字典中的key必须为不可变对象
- 判断字典中是否存在这个key
'Thomas' in d
- dictionary.get(查找是否存在的值,不存在时返回的值)
d.get('Thomas', -1)
- 没有第二个参数时,不存在key的话返回None、
- 删除key
d.pop(key)
- dictionary.items() 返回dict_items形式:(key,value),用list(dictionary.items())转成列表 但在for循环中不用转换
- 同时迭代key和value
for k, v in d.items()
生成器(generator)
- 将列表生成器外的中括号变成小括号即为生成器(generator)
g = (x * x for x in range(10))
- 通过
next(g)
可获得生成器的下一个返回值 - 更好的方法是用迭代
for n in g:
- 当一个函数中包含yield时,这个函数就是一个generator
- 函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行
- 同样的,一般我们用for迭代来调用
函数
def nop():
pass #pass的作用是占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass,让代码能运行起来
####################
if age >= 18:
pass
列表等作为参数传递进函数时,是引用(相当于C中传递指针).如果不想改变原变量的值,就要用copy方法(import copy)
对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的
python中的函数可以同时返回多个值,这实际上是返回了一个tuple
x,y=fun(z)
默认参数
- Python函数在定义的时候,默认参数L的值就被计算出来了,因为默认参数L也是一个变量,每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的了。所以,默认参数必须指向不变对象!
- 如果不按顺序提供部分默认参数,例如倒数第二个使用默认参数而最后一个传入参数,则最后一个参数需要加上参数名
enroll('Adam', 'M', city='Tianjin')
- 可变参数
- 形参前加上*,则传入的参数自动视为tuple
- 如果已经有了list或tuple而要调用可变参数,则在传入实参时加上*即可
nums = [1,2,3]
calc(*nums)
- 关键字参数
- 可以传入字典
- 形参语法:
def person(name, age, **kw):
- 实参语法:
person('Adam', 45, gender='M', job='Engineer')
- 如果已经有了字典而要调用可变参数,则在传入实参时加上**即可
extra = {'city': 'Beijing', 'job': 'Engineer'}
person('Jack', 24, **extra)#person获得的是extra的拷贝,不改变extra
受限制的关键字参数
- 上面的语法无法限制将要传入的内容
- 形参语法:
def person(name, age, *, city, job):
- 当前面有可变参数时就不用加单独的*了
def person(name, age, *args, city, job):
- 当前面有可变参数时就不用加单独的*了
- 命名关键字参数相较于普通参数的好处在于可以不按照顺序传入实参,提高代码可读性
- 解决了可变参数后面不可传入参数的问题
参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数
- 对于任意函数,都可以通过类似func(*args, **kw)的形式调用它,无论它的参数是如何定义的
类
- 类对象和实例对象
- 直接定义在类名下的都是类对象
self.age = age
- 类对象可以被多有实例访问
- 相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性
- 直接定义在类名下的都是类对象
- 如果不加限制,我们可以给一个类对象绑定任意变量,但是很多是有我们只希望绑定限定的变量,此时需要
__slots__
- 该限制对继承后的子类无效
- 除非在子类中也定义
__slots__
,这样,子类实例允许定义的属性就是自身的__slots__
加上父类的__slots__
class Student(object):
__slots__ = ('name', 'age')#此时Student类创建的对象只能绑定name和age变量
- 如果不加限制,我们可以给类变量绑定任意值,但很多时候我们只希望绑定限定的值,但是为此新创一个set方法太麻烦,此时我们可以运用
@property
- 如下图,如果不加
@score.setter
则为只读,不可自己绑定值
- 如下图,如果不加
class Student(object):
@property
def score(self):
return self._score
@score.setter
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self._score = value
#此时我们可以直接用s.score = 60来绑定值而且不用做错误检查
- 给实例对象绑定类方法
- 注意这只是对单个对象绑定,对该类的其他对象并没有绑定
- 注意这只是对单个对象绑定,对该类的其他对象并没有绑定
- 给类绑定类方法
- 该类创建的的所有对象都公用一个方法
- 该类创建的的所有对象都公用一个方法
- 类的属性前加双下划线可将此属性私有,外部无法访问
- 实际上是可以被访问的,是解释器将
__method
改为了_Class__method
- 实际上是可以被访问的,是解释器将
class a(object):
def _init_(self,name,score):
self.__name=name #_name将name私有
self.__score=score
- 当创建实例时,我们可以用
_init_(self,x,y)
强制绑定某些属性(例如x,y)
- 此时不可传入空参数,并且self参数不用传入
- 类中的函数第一个参数永远是self并且不用传递该参数
- 类的继承
-语法:class son(father):
多重继承class son(father1, father2):
- isinstance函数可以判断一个变量是否是某个类型或者其父类型
isinstance(var,type) #返回布尔型
- dir函数或者一个对象的所有属性和方法,返回一个包含字符串的list
- 函数内部,在声明变量前加入global关键词,则此变量被视为全局变量,而函数中如果有局部变量赋值,在赋值前不能使用,哪怕有同名的全局变量
- 返回对象的状态
- getattr()、setattr()以及hasattr()
- getattr()、setattr()以及hasattr()
模块
- 为了避免模块名字的冲突,可以把模块放在包里
- 此时模块名的前面要加上包名
- 每个包里都有一个
_init_.py
文件,不然这个包就会被当成普通目录 - 这个文件本身就是一个模块,她的模块名就是包本身
- 所有模块的第一个字符串都被视为模块的文档注释
- 模块内以下划线开头(一个两个都可)的变量或函数被视为内部变量,不该被外部引用
错误处理
try:
print('try...')
r = 10 / int('2')
print('result:', r)
except ValueError as e:
print('ValueError:', e)
except ZeroDivisionError as e:
print('ZeroDivisionError:', e)
else:
print('no error!')
finally:
print('finally...')
print('END')
- 当我们认为某些代码可能会出错时,就可以用try来运行这段代码,如果执行出错,则后续代码不会继续执行,而是直接跳转至错误处理代码,即except语句块,执行完except后,如果有finally语句块,则执行finally语句块,至此,执行完毕
- Python的错误其实也是class,所有的错误类型都继承自BaseException,所以在使用except时需要注意的是,它不但捕获该类型的错误,还把其子类也“一网打尽”
- 出错后如果在本层没有被捕获,则会返回到上一层,直到被捕获或者退出程序
- 所以当捕获错误时,本层可能没有出错
- 出错的时候,一定要分析错误的调用栈信息,才能定位错误的位置
I/O
with open('/path/to/file', 'r') as f:#with将open大开的文件流给f
print(f.read())#with在缩进的代码执行完毕后会自动关闭文件流
- 前面的‘r’表示可读,而二进制为’b’,写为’w’,追加为’a’
- sys模块中的argv变量储存了所有命令行参数
- 存为字符串list