Collecting Parameters
参数前面加一个星号*,则参数是一个tuple
def print_params(*params):
print params
>>> print_params(1, 2, 3)
(1, 2, 3)
如果在参数前面加上两个参数,那么就是一个字典dict
def print_params_4(x, y, z=3, *pospar, **keypar):
print x, y, z
print pospar
print keypar
代码的结果如下:
>>> print_params_4(1, 2, 3, 5, 6, 7, foo=1, bar=2)
1 2 3
(5, 6, 7)
{'foo': 1, 'bar': 2}
>>> print_params_4(1, 2)
1 2 3
()
{}
星号也可以进行以上过程的逆过程
def add(x, y): return x + y
params = (1, 2)
>>> add(*params)
3
全局变量和局部变量
全局变量会被局部变量覆盖,如果还想访问全局变量,那么可以以globals()的方法来引用它>>> def combine(parameter):
print parameter + globals()['parameter']
...
>>> parameter = 'berry'
>>> combine('Shrub')
Shrubberry
如果在一个函数内给一个被引用的函数赋值,那么它将自动变成局部变量,如果要避免这种情况,需要声明global
>>> x = 1
>>> def change_global():
global x
x = x + 1
>>> change_global()
>>> x
2
NESTED SCOPES(层状作用域)
def multiplier(factor):
def multiplyByFactor(number):
return number*factor
return multiplyByFactor
在某些特殊的场景下,用一个函数来“创造”其他的函数可以用这种特殊的方法:
>>> double = multiplier(2)
>>> double(5)
10
>>> triple = multiplier(3)
>>> triple(3)
9
>>>multiplier(5)(4)
20
但是这样的话,内部函数不能访问外层的域的变量,但是在python3中可以使用nonlocal来声明
Python中的函数式编程
函数式编程三个有用的东西:map filter reduce(python3中在functools模块里面)map 和 filter函数在这个版本中并不是很有用的说,你可以用List comprehension来代替。
>>> map(str, range(10)) # Equivalent to [str(i) for i in range(10)]
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
You use filter to filter out items based on a Boolean function:
>>> def func(x):
...
return x.isalnum()
...
>>> seq = ["foo", "x41", "?!", "***"]
>>> filter(func, seq)
['foo', 'x41']
>>> [x for x in seq if x.isalnum()]
['foo', 'x41']
在这种情况下可以用lambda表达式
filter(lambda x: x.isalnum(), seq)
['foo', 'x41']
reduce函数无法被取代,它的功能是,将一个sequence的第一个元素与第二个元素进行操作,
将结果与第三个元素进行同样的操作直到所有的序列都完毕。
>>> numbers = [72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33]
>>> reduce(lambda x, y: x+y, numbers)
1161
当然如上的操作可以用sum()来代替。
Python 面向对象
私有方法,在方法名以__结尾class Secretive:
def __inaccessible(self):
print "Bet you can't see me..."
def accessible(self):
print "The secret message is:"
self.__inaccessible()
>>> s = Secretive()
>>> s.__inaccessible()
Traceback (most recent call last):
File "<pyshell#112>", line 1, in ?
s.__inaccessible()
AttributeError: Secretive instance has no attribute '__inaccessible'
>>> s.accessible()
The secret message is:
Bet you can't see me...
Python中类的域
每当你定义一个class,在class内部的成员变量,所有的类的实例都能访问它,比如:
class MemberCounter:
members = 0
def init(self):
MemberCounter.members += 1
>>>m1 = MemberCounter()
>>>m1.init()
>>>MemberCounter.members
1
>>>m2 = MemberCounter()
>>>m2.init()
>>>MemberCounter.members
2
>>> m1.members
2
>>> m2.members
2
与函数的域类似,当你给实例中的成员赋值时,本地变量将会覆盖class域的变量:
>>> m1.members = 'Two'
>>> m1.members
'Two'
>>> m2.members
2
查看超类关系
>>> issubclass(SPAMFilter, Filter)
True
>>> issubclass(Filter, SPAMFilter)
>>> issubclass(SPAMFilter, Filter)
True
>>> issubclass(Filter, SPAMFilter)
False
查看实例关系
>>> s = SPAMFilter()
>>> isinstance(s, SPAMFilter)
True
>>> isinstance(s, Filter)
True
>>> isinstance(s, str)
False
>>> s.__class__
<class __main__.SPAMFilter at 0x1707c0>
查看是否包含某个方法
>>> hasattr(tc, 'talk')
True
>>> hasattr(tc, 'fnord')
False
查看函数是否能够被调用
>>> callable(getattr(tc, 'talk', None))
True
>>> callable(getattr(tc, 'fnord', None))
False
增加一个属性
>>> setattr(tc, 'name', 'Mr. Gumby')
>>> tc.name
'Mr. Gumby'