Python的感悟笔记


杂项
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 conditionrepr:取得对象的字符串的规范表示,一般来说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,否则因为作用域的原因,会创建函数作用域内的xnonlocal 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 内置函数http://jianfeihit.iteye.com/blog/1835272
模块部分
每个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 #自定义属性

评论关闭