Python真是灵活又强大!函数篇

一、定义一个函数

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
  • 函数的第一行语句可以选择性地使用文档字符串,用于存放函数说明。
  • return (表达式) 结束函数,选择性地返回一个值。不带表达式的return相当于返回 None。(选择性使用)
  • 注意: python在定义函数参数时,不需要指明类型。
def area(width,height):
	return width*height
w=10
h=5
print("width=",w,",height=",h,",area=",area(w,h))

width= 10 ,height= 5 ,area= 50	#输出

二、参数传递

在python中,类型属于对象,变量是没有类型的。

str1='I love you'

以上代码中,'I love you’是string类型,而变量a是没有类型的,它仅仅是一个对象的引用(一个指针),可以指向string类型对象,也可以指向int类型对象。


c++的函数参数传递:

  • 函数里的形参是一般变量,在函数里面改变变量的值,不会改变主函数里实参的值。
  • 指针就是地址变量,在函数里改变地址变量的值时(就是说改变指针的指向),不会改变主函数实参地址变量的值。
  • 只有在函数里改变指针所指向的变量的值时,主函数实参指针所指向的变量的值才会改变。

值传递: 实参a的值传给形参x,实参b的值传给形参y。这里的x与a只是值相等了,但是两个不同的内存单元。好比一班和二班两位同学,只是名字都叫张三,却是两个不同的人。同理,b和y也类似于一班和二班另两位同学,只是名字都叫李四,却是不同的两人。在swap函数中,只是对x和y操作,类似于只是二班的张三和李四发生了点变化。他们的变化是不会影响一班的张三和李四的。所以x和y的变化不会影响a和b。因为这是四个不同的内存单元。

地址传递: 实参&a(a的地址)传给形参x,实参&b(b的地址)传给形参y。这样的话,x就指向了a,y也指向了b。代码中temp=*x;就等价于temp=a。 同理,*x=y; 等价于a=b;y=temp;等价于b=temp;这里对x和y操作,实际上就是对a和b的操作,所以会影响a和b的值。

#include
using namespace std;
void change(int *x,int *y)
	{
		int *temp;
		temp=x;
		x=y;
		y=temp;
		cout<<"changing... x="<<*x<<",y="<<*y<<endl;
	}
int main()
{
    int a=10,b=8;
	change(&a,&b);
	return 0;
}

Python的参数传递:
在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。

  • 不可变类型: 类似 c++ 的值传递,变量赋值a=5后再赋值a=10,这里实际上是形成了一个新的int型对象10,再让a指向它,而5被丢弃了,不是a的值发生改变,相当于形成了新的a。
def add(number):
	number+=1
a=1
add(a)
print(a)

1	#输出
  • 可变类型: 类似 c++ 的地址传递,变量赋值list1=[1,2,3,4]后在赋值list1[2]=5,则是让list1的第三个元素值发生改变,本身list1并没有发生改变,知识内部的部分值被修改。
def change(list1):
	list1[3]=5
list2=[1,2,3,4,5,6]
change(list2)
print(list2)

[1, 2, 3, 5, 5, 6]	#输出

三、参数

以下是调用函数时可使用的参数类型:

  • 必需参数
  • 关键字参数
  • 默认参数
  • 不定长参数

必需参数:
必需参数必须以正确的顺序传入函数,调用时的参数的数量必须和声明时的一样。

def FirstFunction(age):
	print('lily'+age+'岁了!')
FirstFunction('18')

lily18岁了!	#输出

不加参数就会报错。

def FirstFunction(age):
	print('lily'+age+'岁了!')
FirstFunction(18)

#错误提示
TypeError: can only concatenate str (not "int") to str

所以18只能用字符串表示。


关键字参数:
函数调用时通过关键字参数来确定传入的参数值。
使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 能够用参数名匹配参数值。

def FirstFunction(name,age):
	print(name+age+"岁生日快乐!")
FirstFunction(age='18',name='Mary')

Mary18岁生日快乐!	#输出

默认参数:
调用函数时,如果没有传递参数,就会使用默认参数。

def FirstFunction(name,age='20'):
	print(name+age+"岁生日快乐!")
FirstFunction(name='Mary')

Mary20岁生日快乐!	#输出

不定长参数:
你可能需要一个函数能处理比当初声明时更多的参数,这些参数叫做不定长参数。

  • 加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。(未命名指的是不指定参数名)
def SecondFunction(arg,*tuple):
	print(arg)
	print(tuple)
SecondFunction(10,19,78,99)

#输出
10	
(19, 78, 99)
  • 如果参数中需要指定参数,那么必须用关键字表示。
def text(*tuple,name):
	print("第一个元素:",tuple[1])
	print(name)
text(1,2,3,4,name="xingxing")

#输出
第一个元素: 2
xingxing
  • 如果在函数调用时没有指定参数,它就是一个空元组。
def ThirdFunction(arg,*tuple):
	print(arg)
	print(tuple)
ThirdFunction(10)

#输出
10
()
  • 加了 ** 的参数会以字典的形式导入。
def FirstFunction(arg,**dict):
	print(arg)
	print(dict)
FirstFunction(10,a=18,b=81)

#输出
10
{'a': 18, 'b': 81}
  • 单独出现 * 后的参数必须用关键字传入。
    调用函数时,使用的关键字必须与定义时的参数名相同。
def FirstFunction(number1,number2,*,number3):
	print(number1+number2+number3)
FirstFunction(10,8,number3=31)

49	#输出
def FirstFunction(number1,number2,*,number3):
	print(number1+number2+number3)
FirstFunction(10,8,c=31)
#错误提示
TypeError: FirstFunction() got an unexpected keyword argument 'c'

四、匿名参数

所谓匿名,即不再使用def来定义函数。

  • lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
  • lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
  • 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
    语法:
    lambda 函数的参数 :函数的返回值
sum=lambda var1,var2:var1+var2
print("adding... sum=",sum(10,29))

adding... sum= 39	#输出

五、函数文档

函数文档是用来解释函数的作用,但程序指挥默认输出第一行,而且函数文档只能写在函数内的第一行。

def MyFunction(name):
	'函数文档,打印名字'
	'hello'
	print(name)
MyFunction('liu')
print(MyFunction.__doc__)

#输出
liu
函数文档,打印名字

也可以这样:

def MyFunction(name):
	'函数文档,打印名字'
	'hello'
	print(name)
help(MyFunction)

#输出
Help on function MyFunction in module __main__:

MyFunction(name)
    函数文档,打印名字

你可能感兴趣的:(Python)