杂项
- Python是强类型的,在python中等号的语意是"绑定"将变量与实际对象
- 没有++, --
- 有+=
- 修改str内容:s = s[:7] + 1 + s[8:] #修改s[7]
- 成员函数不要忘记加self参数
- 连接字符串和数字:s + str(1)
- event.keysym =>得到按键的名称
- Python中总共有三个“代”,所谓的三"代”就是三个链表,也就是我们上面所提到的可收集对象链表。当各个代中的对象数量达到一定数量时将触发Python的垃圾回收。
- 分代收集的思想就是活的越久的对象,就越不是垃圾,回收的频率就应该越低。所以当Python发现进过几次垃圾回收该对象都是reachable,就将该对象移到二代中,以此类推。那么Python中又是如何检查各个代是否达到阀值的呢?Python中每次会从三代开始检查,如果三代中的对象大于阀值将同时回收3,2,1代的对象。如果二代的满足,将回收2,1代中的对象。
语法基础部分
字符串
- 转义符:\
- 自然字符串:r“…” 没有转义符的字符串
- unicode字符串:u”..."
- 字符串连接:’a’ ‘b’ => ‘ab’相邻放着的字符串会连接成一个新字符串
- 没有char类型
字符串函数
- s[0:2]截取子串0-1 #也可用于列表,元组
- s[2]截取index=2的字母
- s[0:-1]从头到倒数第二个
- s[:-1]从头开始
- s[-1:]到末尾
- s[:]全部
- s.strip():去除前面和后面的空格,并返回,s并不变
- s.lstrip(‘,’)/rstrip():去除左边、右边的特定字符
- 查找:s.index(‘123’,[l],[r])
- 查找:s.find(‘123’,[l],[r]) 和index的不同:index没找到时会抛出异常,find会返回-1
- 比较:cmp(s1, s2) :不在string模块中,相等时返回0
- 共同子串长度:len(s1 and s2)
- s = "abC ABc"
print s.lower()
print s.upper()
print s.swapcase() #ABc abC
print s.capitalize() #Abc abc
print string.capwords(s) #Abc Abc
- 翻转字符串:s[::-1]
- 分割字符串:s[s.find(‘,’) + 1 : ]
- 分割字符串:s.split(‘,’)
- 连接字符串:delimiter = ‘,‘
mylist = [‘Brazil‘, ‘Russia‘, ‘India‘, ‘China‘]
print delimiter.join(mylist)
- 子串个数:s.count(‘a’,[l],[r])
- 替换:s.replace(‘a’, ‘b’, [count])
- s.startswith(‘a’,[l],[r])
- s.endswith(‘a‘,[l],[r])
- s.islower()
- s.isupper()
- s.isalnum()
- s.isalpha()
- s.isdigit()
- string.atoi(s,[base])
- string.atol(s,[base])
- string.atof(s,[base])
- ‘a’ in s
控制流
- for...else
for i in range(0,5):
print (i)
else:
print (“loop is over")
=>打印0,1,2,3,4,loop is over
range(l,r)不包含r,即代表[l,r)
- while…else:和for...else类似
while True:
if …:
break
else:
print (“loop is over”)
- else语句总会执行,在for/while条件问False时执行且执行一次
运算符
- ** 幂
- // 取整除
- 三段式表达式: val1 if con else val2
如果con为True:返回val1
如果con为False:返回val2
- 类似的还有:con and val1 or val2
注意,如果val1为False时表达式不成立=》将val封装在list中
(con and [val1] or [val2] )[0]
- list comprehension列表推导式:可以快速遍历列表
[函数(i) for i in 某个list]
[函数(i) for i in 某个list if cond(i)]
- assert condition
- repr:取得对象的字符串的规范表示,一般来说eval(repr(obj)) == obj
函数部分
- 所有参数都是按值传递
def change1(x):
x += 10
def change2(l):
l.append([1,2,3,4]);
l = [10,20,30];
change2( mylist );
print my list #[10, 20, 30, [1,2,3,4]]
x=1
change1(x)
print x #1
以上l改变而x没变的原因是:
l是非内置类型,可以理解为指针,所以通过l的复制品l’,仍然指向相同的list
x是内置类型,所以按值传递的x’改变后,原x还是1
- 作用域:规则和C一样
- global x==>全局域中有x,则可以访问该x,否则因为作用域的原因,会创建函数作用域内的x
- nonlocal x 类似,一般用于嵌套函数中
- 默认参数值:规则和C一样
def fun(x, y=0, z=1): ...
- 不定长参数:用*表示 | 用**表示
def varl(x, *listparam):
传入方法: varf(x, 10, 20) #listparam=[10,20]
def vard(x, **dicparam)
传入方法: varf(x, y=1, z=2)#dicparam={y:1, z:2}
- 关键参数:可以使用名字来规定某个默认参数的值
fun(1, z=3) #跳过某个参数
fun(z=3, x=1) #乱序传参数
- 返回值:规则和C一样
- docString:类似文档的作用
def docf():
‘’ this is docf’‘
printdocf.__doc__#this is doc注意,没有调用函数,而是直接写函数名
- 匿名函数:
sum =lambdaarg1, arg2: arg1 + arg2;#只能是一个表达式,不能访问global,不能包含多个表达式,不能print
print sum(1,2)
- 嵌套函数:
def f1():
def f2(): ...
f2()
f2可以访问f1的变量,修改=>记得作用域、内置类型、非内置类型
可以在f2中用nonlocal x声明f1中的内置类型变量x
- 闭包:
嵌套函数,并且外部函数返回嵌套函数
def f1(a3):
a1 = 1
a2 = [1]
def inf():
#nonlocal a1, a2
a1 += 2 #报错
a3 += 2 #报错
a2[0] += 2
return a1, a2, a3
return inf
a3 = 2
a = f1(a3)
t = a()
注意:1. 对f1中的非内置类型,在f2中直接修改
2. 对f1中内置类型,需要加上nonlocal才能在f2中修改
- 迭代器,生成器和yield
- 迭代器:实现迭代器接口的可以用for循环读取内容
- 生成器:包含yield语句的函数会被编译成生成器,不像一般的函数会生成值后退出,生成器函数在生成值后会自动挂起并暂停他们的执行和状态,他的本地变量将保存状态信息,这些信息在函数恢复时将再度有效
def gen(n):
for i in range(n):
yield i * 2
for i in gen(3):
print i
也可以通过 i = gen(3)=>i.next()访问下一个内容
gen.close()提前关闭生成器
def gen2():
val = yield 1
print val #content
val = yield 2
print val #nothing
g = gen2()
print g.next()#1
print g.send(‘content‘)#2
通过g.send(…)传给生成器一个值,注意第一次必须用next
模块部分
- 每个Python模块都有它的__name__,如果它是‘__main__‘,这说明这个模块被用户单独运行,我们可以进行相应的恰当操作。
xx.py:
if __name__ == ‘__main__‘:
print ‘This program is being run by itself’ #
python xx.py
else:
print ‘I am being imported from another module’ #import xx
- 当Python遇到导入语句时,首先检查某块是否已经导入(sys.moudles),如果已经导入就直接使用,如果没有,那么:
0. 创建一个新的空模块对象(其实是个字典);
1. 将这个对象加入sys.modules字典中;
2. 载入模块的代码对象(如果必要会进行编译);
3. 在新的模块命名空间中执行代码并分配到相应的模块对象上;
4. 如果将模块当做脚本来运行,将会在__main__之后载入模块。
- 内置模块、标准模块:安装完Python便有的
- 扩展模块:自定义或者外部安装的模块
面向对象部分
- Python中所有类成员都是公共的,所有方法都是有效的
- 成员名字加__,如__xx则为私有:访问会报错
- __del__:析构
- __init__:构造
- __str__:在我们对对象使用
print
语句或是使用str()
的时候调用 - __lt__(self, other): 当使用 小于 运算符(<)的时候调用。类似地,对于所有的运算符(+,>等等)都有特殊的方法
- __getitem__(self,key): 使用
x[key]
索引操作符的时候调用 - __len__:对序列对象使用内建的
len()
函数的时候调用 - 调用父函数:super
还记得之前的体系吗
class Derived(Base):
def __init__(self):
Base.__init__()
通过这种方法调用Base的函数,缺点是如果Base改名了,所有继承自Base的类都需要改
现在可以通过super(Derived, self).__init__()调用了,但是有以下注意点
1. Base必须继承自object,否则报错
2. 所有继承体系中必须都用super()否则会出问题
3. super会保证存在多继承時所有構造函数调用一次且只一次,按照拓扑排序顺序调用
4. super并不是一个函数,是一个类名,形如super(B, self)事实上调用了super类的初始化函数,产生了一个super对象
- 类属性:
class A:
i = 0
i为A的类属性,可以通过A.i的方式访问i
class A:
i = 0
def __init__(self, c):
self.i = c
print A.i #0
a = A(1)
print A.i #0
print a.i #1
这是因为self.i生成了一个非static的同名的i
那如何才能改A.i那?相信大家已经猜到了,将self.i改为A.i即可
此时打印的结果为0 1 1
- property =>提供getter和setter
class A(object):
def __init__(self):
self.__x=None
@property
def x(self):
return self.__x
@x.setter
def x(self,value):
self.__x=value
@x.deleter
def x(self):
del self.__x
注意:
1. A需要继承自object
2. @property相当于getter
- 类方法:
@classmethod
def classf(cls):...
调用时可以通过类的实例.classf()
或者通过类.classf()均可,不需要参数
可以访问类属性,不能访问实例属性
- 静态方法:
@staticmethod
def staticmd():...
静态方法:无法访问类属性、实例属性,相当于一个相对独立的方法,跟类其实没什么关系。
- 命名空间:
python搜索一个标识符的顺序是"LEGB"
L(local):表示在一个函数定义中,而且在这个函数里面没有再包含函数的定义。
E(enclosing function):表示在一个函数定义中,但这个函数里面还包含有函数的定义,其实L层和E层只是相对的。
G(global):是指一个模块的命名空间,也就是说在一个.py文件中定义的标识符,但不在一个函数中。
B(builtin):是指python解释器启动时就已经具有的命名空间,之所以叫builtin是因为在python解释器启动时会自动载入__builtin__模块,这个模块中的list、str等内置函数的就处于B层的命名空间中。
对于Python built-in names组成的命名空间,它在Python解释器启动的时候被创建,在解释器退出的时候才被删除;
对于一个Python模块的global namespace,它在这个module被import的时候创建,在解释器退出的时候退出;
对于一个函数的local namespace,它在函数每次被调用的时候创建,函数返回的时候被删除。
这里需要注意的一点是,nonlocal和global是不一样的
nonlocal会从里向外找
global会直接定位于模块命名空间内
- 方法和函数的区别:(来源http://www.v2ex.com/t/38692)
方法是一种特殊的函数。
python中,函数(方法)并不是依附与类才能存在。函数并不只是在类中定义。这种直接在模块中而不是类中定义的函数(方法),叫做函数。
而方法(method),是依附于类的,他们定义在类中,是属于类的,但是他们本质上,还是一个函数。方法的第一个参数不一定必须是self。
这么说吧,凡是def foo()这种,都是函数,在类中定义的函数,就是方法。
总结:
方法:类内普通方法,类方法
函数:普通函数,类内的静态方法
- 多态性:和C++的多态性不一样
C++是静态语,在编译时绑定,多态是指运行时多态,即使用指向子类的父类指针,可以调用子类函数
Python是动态语言,在运行时绑定,它的多态是指随时可以通过setattr这样的方法添加属性,方法,类似反射?(http://www.cnblogs.com/brucejia/archive/2013/05/16/3082112.html)
异常部分
- 捕捉异常:
try: ….
except xxException / (exception1, exception2):
处理特定错误的逻辑
except:
处理其他错误的逻辑
[else:]
[finally:]
- 引发异常:
raise xxException
在except语句中添加raise传递异常
- 自定义异常:
class myException(Exception):
...
使用时 raise myException(参数…)
try:...
except myException,
e: e.xxx #自定义属性