列表生成式(映射list)
[expression for i in Iterable]
, 也可以嵌套: [expression for i in Iterable1 for j in Iterable2]
, 甚至可以加入判断条件 [expression for i in Iterable if condition]
. 循环也可以像一般for循环支持多循环变量. 迭代产生列表时若某项出错,则会报错生成失败.
列表生成器使用一句的语法用生成器生成列表的各个项, 仅适用于列表,而且记得加[..]
就是将迭代的i进行相应表达式操作, 生成相应一个新的列表, 若加入判断条件,列表长度可能改变. 例如
[ 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']
d = {'x': 'A', 'y': 'B', 'z': 'C' }
[k + '=' + v for k, v in d.iteritems()]
#->['y=B', 'x=A', 'z=C']
L = ['Hello', 'World', 'IBM', 'Apple']
[s.lower() for s in L]
#->['hello', 'world', 'ibm', 'apple']
g=( x*x for x in range(1,11) );g
#-><generator object <genexpr> at 0x104feab40>
A=[]
for i in g:A.append(i);
将中括号变成小括号, 返回的将是生成器
而不是列表.
sorted排序函数
sorted(list[,func])
: 对列表排序, 默认从小到大. 可以自定义提供函数func(x,y)
来自定义排序, 默认当x < y 返回-1 (即不变顺序), x > y返回1 (即变顺序), x==y 返回0 (即不变顺序).
# 缺省从小到大,所以默认函数
def funcsort(x,y):
if x<y:return -1
elif x>y:return 1
else return 0
# 按字符第一个字母(不考虑大小写)排序
def strsort(x,y):
x1=x[0].upper()
y1=y[0].upper()
if x1<y1:return -1
elif x1>y1:return 1
else return 0
lambda函数 (匿名函数)
快速定义单行单表达式操作并返回的最小函数, lambda函数是从lisp借来的.虽然说lambda函数,但其实他是个语句关键词而不是一个函数.
func=lambda 参数: 表达式
等价于def func(参数):return 表达式
, 也可以直接(lambda 参数:表达式)(实参)
直接调用.
lambda函数代码较简, 但只适用于单个表达式, 并且不能包含命令(直接return),但可接受多参数. 如果函数内容较复杂,建议用def func().lambda函数一个重要应用是在高阶函数中作为函数参数传入.
# 以下例子定义一个函数,若collapse为真,执行压缩字符串空白; 否则返回字符串.
# 其本事是函数,因为核心执行的是lambda部分.
processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)
偏函数
是一种高阶函数,其实就是可以重新设定指定函数某些参数的默认值,返回一个新的函数.
使用functools.partial(func,*args,**kw)
来进行重新定义默认值, 其中kw就是arg=val
形式,而args就是一般的参数,会从原函数参数左边插入该些参数. 例如
int2 = functools.partial(int, base=2)
int2('1000000') #>>> 64
# 等价于 :
int('1000000', base=2) #>>> 64
# 也可在偏函数中像原函数一样指定值:
int2('1000000', base=10) #>>> 1000000
# 指定*args部分:
max10 = functools.partial(max,10);
# 传入参数后等价于max(10,5,6,7)
max10(5,6,7) #>>>10
闭包和返回函数
返回函数就是将一个函数作为结果返回. 当返回的函数在一个函数内时(就是函数内的函数), 称之为闭包(closure), 此时相关参数和变量都保存在返回的函数中.
返回的函数是一个新的对象, 存有相应的信息.由于只是返回函数, 并没有执行返回函数内的返回结果, 只有在再次调用时才起效.
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax = ax + n
return ax
return sum
f = lazy_sum(1, 3, 5, 7, 9)
f() #>>> 25
在返回函数返回多个闭包时,注意返回函数不要引用任何循环变量或者后续会变化的变量.
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs
f1, f2, f3 = count()
f1();f2();f3(); #>>> 9; 9; 9
### 没有预期结果原因是, 返回的是列表是三个闭包, 这三个闭包的值引用的是i, 而i的值在返回阶段才执行
# 正确写法:
def count():
fs = []
for i in range(1, 4):
def f(j):
def g():
return j*j
return g
fs.append(f(i))
return fs
f1, f2, f3 = count()
f1();f2();f3(); #>>> 1; 4; 9
装饰器 Decorator
在代码运行期间动态增加功能的方式,称之为“装饰器”。装饰器本质是高阶函数, 就是将函数作为参数进行相应运作. 装饰器在python中在函数/对象方法定义前使用@
符号调用. 装饰器可以在函数运行前进行一些预处理, 例如检查类型等.
@dec1
@dec2(arg1,arg2)
def test(arg):
pass
以上代码等于dec1(dec2(arg1,arg2)(test(arg)))
动态类和对象方法:
python动态语言,可以对类/对象直接添加新的属性和方法. 对类进行添加,所有实例都起效, 对某个实例添加, 只能对该实例起效,其余实例不受影响. 注意添加方法需要使用self,因为会传递实例本身.
class Student(object):pass
s1=Student();
s2=Student();
s1.hi=10; s1.hi; # 对实例添加新属性
# -> 10
s2.hi;
# -> 'Student' object has no attribute 'hi'
Student.hi=11; # 对类添加新属性
s1.hi; #实例不受新添加类属性影响
#-> 10
s2.hi; # 新属性对另一实例起效
#-> 11
def prints(self):print "Hello!";
def printss():print "Hi!";
s1.printss=printss;
s1.printss #-> <function __main__.printss>
s1.printss(); # 其实此时并不是绑定的方法,而只是调用一个函数.
# -> Hi!
s2.printss();
#-> 'Student' object has no attribute 'printss'
Student.printss=printss
s2.printss()
#-> printss() takes no arguments (1 given)
Student.prints=prints;
s2.prints # 绑定的方法,会传递self
#-> <bound method Student.prints of <__main__.Student object at 0x050D6770>>
s2.prints()
#-> Hello!
使用MehodType函数可以也将函数绑定为类的方法. 第二个参数为None,第三个参数若为类, 则所有实例都起效; 也可以只绑定某个实例对象(第二个参数为实例,第三个参数为类或不填), 此时其余对象不具有该方法.
from types import MethodType
def set_score(self, score):
self.score = score
s1=Student();s2=Stundet();
s1.MethodType(set_score, s1, Student)
s1.set_score(60),s1.score; #-> 60
s2.set_score(60); #-> AttributeError: 'Student' object has no attribute 'set_age'
Student.set_score = MethodType(set_score, None, Student)
s2.set_score(80);s2.score; #-> 80
限制类属性 __slots__
:
__slots__ = ('name', 'age')
可以限制类属性只能有列出的来的几种. 添加或指定新属性将报错AttributeError.
__slots__
只对当前类起效, 对子类无效. 若子类也定义了slots, 则子类运行的属性则是父类和子类的slots的合集.
对象方法变对象属性的装饰器@property和@*.setter
该装饰器是python内置的,是类中一个高级用法,作用是将一个方法名变成一个对象属性. 类需要继承于object相应的类.
构建相应@property def prop(self):return self._prop
就可以直接obj.prop
来将方法变成获取对象属性的调用形式.而相应@prop.setter def prop(self,value): self._prop=value
就可以实现obj.prop=value
将方法转为对象属性的赋值.而且好处还可以在此加入属性的值的检查. obj._prop只是相应储存的储存地方,名字也是无限制的.
不定义setter而只定义property的话,该属性就是只读的不能修改的!!
例如:
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
@property
def fail(self):
return True if (self.score <60) else False
# (self.score <60) and return True or return False
s = Student()
s.score = 60 # OK,实际转化为s.set_score(60)
s.score # OK,实际转化为s.get_score()
### 60
s.score = 9999
### Traceback (most recent call last):
### ...
### ValueError: score must between 0 ~ 100!
s.fail
### False
s.fail=True
### Traceback (most recent call last)
### ...
### AttributeError: can't set attribute
__future__
模块
__future__
模块用来引入一些新版本的特性, 例如在2.x版本中引入3.x版本的特性.
from __future__ import unicode_literals
引入3.x版本中字符串特性, 使用该语句后,"str"
就已经是unicode的,而2.x版本中的字符串则要使用b"str"
来表示.from __future__ import division
引入3.x中除法特性,3.x中除法默认是精确除法,2.x则是向下取整.例如10/3
2.x的是3,3.x是3.33333.使用该特性后就会采用3.x的特性, 而原有的除法要使用10//3
来表示.
本博文已合并到Python语法汇总中, 不再更新.