Python中的函数相比较于c++和java要好用的多,创建也简单。但要习惯参数的工作原理也是不太容易的。先尽量写一写吧。
1、首先来看两个修改函数参数的例子:
def try_to_change(name):
name="风清扬"
print("函数内",name);
name="东北不败";
try_to_change(name);
print("函数外",name)
看运行结果:
函数内 风清扬
函数外 东北不败
函数内参数修改对函数外的值是没有影响的。上面的代码我们可以等效的这样写:
name="东北不败";
n=name;
n="风清扬";
print(n)
运行结果:
风清扬
下面看看列表作为参数传递的时候:
name=["东方不败","风清扬","令狐冲"];
def change(name):
name[0]="岳不群"
change(name);
print(name)
运行结果:
['岳不群', '风清扬', '令狐冲']
结果是不是有点不同,我们再来看看下面的等效代码:
name=["东方不败","风清扬","令狐冲"];
n=name;
n[0]="岳不群"
print(name)
这个我们应该在前面说过,运行结果为:
['岳不群', '风清扬', '令狐冲']
将同一个列表赋值给两个变量时,这两个变量将同时指向这个列表。要避免这样的情况,就必须创建列表的副本,使用切片的方式。
name=["东方不败","风清扬","令狐冲"];
n=name[:]
2、前面介绍的是一些位置参数,位置参数是按照顺序排列的。接下来来看看关键字参数和默认值。
def hello1(greeting,name):
print("{},{}".format(greeting,name))
def hello2(greeting,name):
print("{},{}".format(greeting,name))
hello1("hello","world");
hello2(greeting="hello",name="world")
hello2(name="hello",greeting="world");
hello2(name="world",greeting="hello")
运行结果是:
hello,world
hello,world
world,hello
hello,world
像这样使用名称指定的参数称为关键字参数,主要优点是用来澄清各个参数的作用。这样每个参数的的意义就清晰了,在用的时候即使顺序错了也没关系。另外,关键字参数最大的有点事可以指定默认值。例如:
str1="hello"
str2="world";
def hello2(greeting=str1,name=str2):
print("{},{}".format(greeting,name))
hello2()
运行结果是:
hello,world
假如我们只想提供name,并让参数greeting使用默认值。
str1="hello"
str2="world";
def hello2(greeting=str1,name=str2):
print("{},{}".format(greeting,name))
hello2(name="东方不败")
运行结果是:
hello,东方不败
3、多个参数的使用。
假如我们在创建函数的时候不知道需要传入多少参数,可不可以使用一个容器作为参数传递呢。
def demo1(*p):
print(p)
demo1("东方不败")
demo1("东方不败","风清扬");
demo1(1,2,3,4,5)
运行结果:
('东方不败',)
('东方不败', '风清扬')
(1, 2, 3, 4, 5)
这里使用一个星号加一个参数,参数前面的星号将提供的所有的值都放在一个元组中,也就是将这些值收集起来。好像前面我们看到过这种情况:在赋值时,带星号的变量收集多余的值。只是一个收集列表一个收集元组。
def number(x,*y):
print("x={}".format(x))
print("y={}".format(y))
number(1,2,3,4,5)
运行结果:
x=1
y=(2, 3, 4, 5)
星号意味着收集余下的位置参数。如果没有可供收集的参数,y将是一个空元组。另外,带星号的参数可以放在其他位置,但是我们需要指定后面参数的名称。
def number(x,*y,z):
print("x={}".format(x))
print("y={}".format(y))
print("z={}".format(z))
number(1,2,3,4,5,z=9)
运行结果是:
x=1
y=(2, 3, 4, 5)
z=9