# -*- coding: cp936 -*-
#P92 6.4 参数魔法 6.4.2 我能改变参数吗
def try_to_change(n):
n = 'Mr. Gumby' #局部作用域(local scope)
name = 'Mr. Entity'
try_to_change(name)
print name
# 列表作参数时,发生变化
def change(n):
n[0] = 'Mr. Gumby'
names = ['Mrs. Entity', 'Mrs. Thing']
change(names) #names发生了改变
print names
#1.为什么要修改参数
# 编写一个存储名字并且能用名字、中间名或姓查找联系人的程序。
# 带3个键的字典
storage = {}
storage['first'] = {}
storage['middle'] = {}
storage['last'] ={}
# 加入一个人名
me = 'Magnus Lie Hetland'
storage['first']['Magnus'] = [me]
storage['middle']['Lie'] = [me]
storage['last']['Hetland'] = [me]
# 输出中间名为'Lie'的人
print storage['middle']['Lie']
# 再加入一个人名
my_sister = 'Anne Lie Hetland' #setdefault字典方法:获得与给定键相关联的值
storage['first'].setdefault('Anne', []).append(my_sister)
storage['middle'].setdefault('Lie', []).append(my_sister)
storage['last'].setdefault('Hetland', []).append(my_sister)
print storage['first']['Anne']
print storage['middle']['Lie']
# 用函数实现上述功能
# 初始化函数
def init(data):
data['first'] = {}
data['middle'] = {}
data['last'] = {}
# 调用函数
storage = {}
init(storage) #调用init()函数
print storage
# 获得名字的函数
def lookup(data, label, name):
return data[label].get(name) #get字典方法:访问字典中给定键的值
print lookup(storage, 'middle', 'Lie') #输出中间名为'Lie'的人名
# 存储人名的函数
def store(data, full_name):
names = full_name.split() #split字符串方法:将字符串分割成序列
if len(names) == 2: #如果names只有首名和末名,插入一个空字符串作为中间名
names.insert(1, '') #insert列表方法:将对象插入到列表中
labels = 'first', 'middle', 'last'
for label, name in zip(labels, names):#zip函数可以进行并行迭代,返回一个元组的列表
people = lookup(data, label, name)#调用获得名字的函数lookup()
if people:
people.append(full_name)
else:
data[label][name] = [full_name]
# 功能的实现
MyNames = {}
init(MyNames) #调用初始化函数init()
store(MyNames, 'Magnnus Lie Hetland') #调用存储人名的函数store()
print lookup(MyNames, 'middle', 'Lie') #调用获得名字的函数lookup()
store(MyNames, 'Robin Hood')
store(MyNames, 'Robin Locksley')
print lookup(MyNames, 'first', 'Robin') #输出首名是Robin的人名
store(MyNames, 'Mr. Gumby')
print lookup(MyNames, 'middle', '') #输出无中间名的人名
print MyNames #输出字典
#2.如果我的参数不可变呢
# 将变量的数值增1的函数
def inc(x): return x + 1
foo = 10; foo = inc(foo); print foo
# 改变参数
def inc(x): x[0] = x[0] + 1
foo = [10] #将值放置在列表中
inc(foo); print foo
raw_input("Press <enter>")
# -*- coding: cp936 -*-
#P97 6.4 参数魔法 6.4.3 关键字参数和默认值
# 位置参数
def hello_1(greeting, name):
print '%s, %s!' % (greeting, name)
def hello_2(name, greeting):
print '%s, %s!' % (name, greeting)
hello_1('Hello', 'world')
hello_2('Hello', 'world')
# 提供参数的名字,可不再需要参数的位置一一对应,称关键字参数
hello_1(greeting = 'Hello', name = 'world')
hello_1(name = 'world', greeting = 'Hello')
hello_2(greeting = 'Hello', name = 'world')
# 在函数中给参数提供默认值
def hello_3(greeting = 'Hello', name = 'world'):
print '%s, %s!' % (greeting, name)
hello_3()
hello_3('Greeting')
hello_3('Greeting', 'universe')
hello_3(name = 'Gumby')
# 在参数中自定义名字,问候语和标点
def hello_4(name, greeting = 'Hello', punctuation='!'):
print '%s, %s%s' % (greeting, name, punctuation)
hello_4('Mars')
hello_4('Mars', 'Howdy')
hello_4('Mars', 'Howdy', '...')
hello_4('Mars', punctuation = '.')
hello_4('Mars', greeting = 'Top of the morning to ya')
#hello_4() name无默认值,会产生异常
raw_input("Press <enter>")
# -*- coding: cp936 -*-
#P99 6.4 参数魔法 6.4.4 收集参数
# 指定参数时加*星号,提供任意多的参数
def print_params(*params): # 星号*将所有值放置在同一个元组中
print params
print_params('Testing')
print_params(1, 2, 3)
# tile需传一个参数,*params可传可不传,数量不限
def print_params_2(title, *params):
print title
print params
print_params_2('Params:', 1, 2, 3) # 星号*收集其余的位置参数
print_params_2('Nothing:') # 可不为*params提供元素
#print_params_2('Hmm...', something = 42) #用*params处理关键字参数时错误
# 处理关键字参数时用**
def print_params_3(**params):
print params
print_params_3(x = 1, y = 2, z = 3) #传递关键字参数 返回字典
# 同时使用* 和 **
def print_params_4(x, y, z = 3, *pospar, **keypar):
print x, y, z
print pospar
print keypar #参数 x,y,z,*pospar,**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 init(data):
data['first'] = {}; data['middle'] = {}; data['last'] = {}
# 获得名字的函数
def lookup(data, label, name):
return data[label].get(name) #get字典方法:访问字典中给定键的值
# 可以存储多个人名的函数
def store(data, *full_names):
for full_name in full_names:
names = full_name.split() #split字符串方法:将字符串分割成序列
if len(names) == 2: #如果names只有首名和末名,插入一个空字符串作为中间名
names.insert(1, '') #insert列表方法:将对象插入到列表中
labels = 'first', 'middle', 'last'
for label, name in zip(labels, names):#zip函数可以进行并行迭代,返回一个元组的列表
people = lookup(data, label, name)#调用获得名字的函数lookup()
if people:
people.append(full_name)
else:
data[label][name] = [full_name]
# 功能的实现
d = {}
init(d) #调用初始化函数init()
store(d, 'Han Solo') #调用可以存储多个人名的函数store()
store(d, 'Luke Skywalker', 'Anakin Skywalker')
print lookup(d, 'last', 'Skywalker')#输出姓为Skywalker的人名
raw_input("Press <enter>")
# -*- coding: cp936 -*-
#P101 6.4 参数魔法 6.4.5 参数收集的逆过程
# 处理元组
def add(x, y): return x + y
params = (1, 2) #在调用前,收集参数
print add(*params)
# 处理字典
def hello_3(greeting = 'Hello', name = 'world'):
print '%s, %s!' % (greeting, name)
params = {'name': 'Sir Robin', 'greeting': 'Well met'}
hello_3(**params)
# 星号只在定义函数(允许使用不定数目的参数)或者调用(“分割”字典或者序列)时才有用
def with_stars(**kwds):
print kwds['name'], 'is', kwds['age'], 'years old'
def without_stars(kwds):
print kwds['name'], 'is', kwds['age'], 'years old'
args = {'name': 'Mr. Gumby', 'age': 42}
with_stars(**args)
without_stars(args)
# 使用拼接(Splicing)操作符“传递”参数,不用关心参数的个数??
def foo(x, y, z, m = 0, n=0):
print x, y, z, m, n
def call_foo(*args, **kwds):
print "Calling foo!"
foo(*args, **kwds)
foo(1, 2, 'a', n = 999, m = 888)
call_foo(1, 2, 'a', 'b', 'c')
#P101 6.4 参数魔法 6.4.6 练习使用参数
# 收集参数 处理关键字参数
def story(**kwds):
return 'Once upon a time, there was a ' \
'%(job)s called %(name)s.' % kwds
print story(job = 'king', name = 'Gumby')
print story(name = 'Sir Robin', job ='brave knight')
params = {'job': 'language', 'name': 'Python'}
print story(**params)
del params['job']
print story(job = 'stroke of genius', **params)
print '\n'
# 收集参数 处理多个值的参数
def power(x, y, *others):
if others:
print 'Received redundant parameters:', others
return pow(x, y)
print power(2, 3)
print power(3, 2)
print power(y = 3, x = 2)
params = (5,) * 2 # (5, 5)
print power(*params)
print power(3, 3, 'Hello, world')
print '\n'
# 处理一般的参数
def interval(start, stop = None, step = 1):
'Imitates range() for step > 0'
if stop is None:
start, stop = 0, start
result = []
i = start
while i < stop:
result.append(i)
i += step
return result
interval(10)
interval(1, 5)
interval(3, 12, 4)
power(*interval(3, 7))
raw_input("Press <enter>")