https://www.jianshu.com/p/168e341fb81c
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段;比如常用的print()
,就是内建函数;通俗来讲,函数就是把代码打包成不通形状的乐高积木,以便可以根据需求调用拼装;当然这种函数叫做自定义函数。
定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可.
特性: 减少重复代码;使程序变的可扩展;使程序变得易维护.
def 函数名(参数列表):
函数体
def hello():
print('Hello World')
#上面是函数主体,下面是调用hello这个函数;
hello()
注意:
一旦函数经过调用并开始执行,那函数外部的程序,就无法再控制函数的执行过程,只能等待函数执行结果;所以return语句代表着函数的结束;
如果未在函数中指定return,那这个函数的返回值为None;
def count(numb1, numb2):
numb3 = numb1 * numb2
return numb3
print(count(3, 4))
参数从调用的意义上来讲,分为形式参数和实际参数,简称"形参"和"实参";形参指的是函数创建和定义过程中小括号内的参数;实参是指函数被调用的过程中传递进来的参数;
实参:可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值;
def data(name, age):
'''
:param name:
:param age:
:return:
'''
print('姓名:{0}\n年龄:{1}'.format(name, age))
data('lain', 23)
def data(name, age, pro):
'''
:param name:
:param age:
:param pro:
:return:
'''
print('姓名:' + name + '\n年龄:' + age + '\n职业:' + pro)
data(pro='CA', name='LAIN', age='28') #不用考虑先后顺序
def data(pro='CA', name='LAIN', age='28'):
'''
:param name:
:param age:
:param pro:
:return:
'''
print('姓名:' + name + '\n年龄:' + age + '\n职业:' + pro)
data() #实参不传参则按照形参赋值的参数进行打印;
data(name='LIMING', age='30', pro='DBA') #实参传参则按照实参传递的参数进行打印;
*args **kwargs
def data(name, age, pro, *hobby):
'''
:param name:
:param age:
:param pro:
:return:
'''
print('姓名:' + name + '\n年龄:' + age + '\n职业:' + pro)
print('兴趣爱好:', *hobby)
data('LIMING', '30', 'DBA', '足球', '跑步', '爬山')
#上面的事例可以理解为打包,既然可以打包那么肯定可以解包
def data(name, age, pro, *hobby):
'''
:param name:
:param age:
:param pro:
:return:
'''
print('姓名:' + name + '\n年龄:' + age + '\n职业:' + pro)
print('兴趣爱好:', *hobby)
a = ['足球', '跑步', '爬山']
data('LIMING', '30', 'DBA', *a)
def data(name, age, pro, *hobby, **mes):
'''
:param name:
:param age:
:param pro:
:return:
'''
print('姓名:' + name + '\n年龄:' + age + '\n职业:' + pro)
print('兴趣爱好:', *hobby)
print('其他信息:', mes)
data('LIMING', '30', 'DBA', '足球', '跑步', '爬山', phone='13452123453', studID='20183511')
如果在函数调用时没有指定参数,它就是一个空字典;
def data(name, age, pro, *hobby, **mes):
'''
:param name:
:param age:
:param pro:
:return:
'''
print('姓名:' + name + '\n年龄:' + age + '\n职业:' + pro)
print('兴趣爱好:', *hobby)
print('其他信息:', mes)
data('LIMING', '30', 'DBA', '足球', '跑步', '爬山')
python中的作用域:局部作用域(L-Local)、闭包函数外的函数作用域(E-Enclosing)、全局作用域(G-Global)、内建函数作用域(B-Built-in);
a = 0
def number(arg1, arg2):
'''
:param arg1:
:param arg2:
:return:
'''
a = arg1 + arg2
print('函数内a的值: ',a)
print('函数内a的内存地址: ',id(a))
number(1, 2)
print('函数外a的值: ', a)
print('函数外a的内存地址: ', id(a))
执行结果:
函数内a的值: 3
函数内a的内存地址: 492495664
函数外a的值: 0
函数外a的内存地址: 492495616
global
修改全局变量a = 0
def number(arg1, arg2):
'''
:param arg1:
:param arg2:
:return:
'''
global a
a = arg1 + arg2
print('函数内a的值: ',a)
print('函数内a的内存地址: ',id(a))
number(1, 2)
print('函数外a的值: ', a)
print('函数外a的内存地址: ', id(a))
执行结果:
函数内a的值: 3
函数内a的内存地址: 492495664
函数外a的值: 3
函数外a的内存地址: 492495664
nonlocal
修改闭包函数外的函数变量a = 0
def number():
'''
:param arg1:
:param arg2:
:return:
'''
a = 1
print('number()函数内a的内存地址: ', id(a))
def soure():
nonlocal a #修改的是外层函数a=1的值
a = 2
print('soure()函数内a的内存地址: ', id(a))
soure()
print('soure()函数外a的内存地址: ', id(a))
number()
print('函数外a的内存地址: ', id(a))
def calc(x,y):
runturn x*y
print(calc(3,4))
用lambda表达式如下
calc = lambda x,y:x*y
print(calc(3,4))
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
递归特性:
data = range(0,1000000)
def digui(data,find):
if len(data) > 0:
middle_pos = int(len(data)/2)
if data[middle_pos] == find:
print('find_name:',find)
elif data[middle_pos] < find:
print('\033[31;1m 右边的值:%s\033[0m',data[middle_pos+1:])
digui(data[middle_pos+1:],find)
else:
print('\033[32;1m 左边的值:%s\033[0m',data[0:middle_pos])
digui(data[0:middle_pos],find)
else:
print('没有找到!')
digui(data,451232)
def sum_number(n):
if n <= 0:
return 0
return n+sum_number(n-1)
print(sum_number(100))
list = [i*i for i in range(10)] #列表推导式,用中括号表示
print(list)
list1 = []
for i in range(10):
list1.append(i*i)
print(list1)
其他事例:
list = [i*i for i in range(10) if i%2 == 0]
print(list)
list = [x*y for x in range(1, 10) for y in range(1, 10) if x >= y]
print(list)
dic = {i:i*i for i in range(5)} #大括号内冒号左右分别是key、value组合
print(dic)
s = {i for i in 'hello world' if i not in 'w'} #集合与字典推导式的区别是key、value组合
print(s)
tup = tuple(i for i in range(5)) #tuple
print(tup)
result = [lambda x:x + i for i in range(5)]
print(result[0](10)) #调用函数时循环结束i的值为4,所以结果为10+4=14
14
result = [lambda x,y=i:x + y for i in range(5)]
print(result[0](10)) #每次循环将i赋值给y,结果为0+10=10
print(result[1](10)) #每次循环将i赋值给y,结果为1+10=11
迭代:通过for循环遍历对象每个元素的过程
我们已经知道,可以直接作用于for循环的数据类型有以下几种:
可以通过python内置的方法Iterable来测试数据类型是否为可迭代对象
from collections import Iterable
print(isinstance('Hello', Iterable)) #字符串是可迭代对象
print(isinstance([1, 2, 3], Iterable)) #列表是可迭代对象
print(isinstance({'a':2, 'b':3}, Iterable)) #字典是可迭代对象
print(isinstance((1, 2, 3), Iterable)) #元组是可迭代对象
print(isinstance({1, 2, 3}, Iterable)) #集合是可迭代对象
print(isinstance(1, Iterable)) #整数是不可迭代对象
运行结果:
True
True
True
True
True
False
可以迭代并且可以被next()函数和iter()调用,并不断返回下一个值的对象就称为迭代器(Iterator);迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往后遍历不能回溯,不像列表,你随时可以取后面的数据,也可以返回头取前面的数据。
通过Iterator可以测试上面的可迭代对象是否为迭代器
from collections import Iterator
print(isinstance('Hello', Iterator)) #字符串不是迭代器
print(isinstance([1, 2, 3], Iterator)) #列表不是迭代器
print(isinstance({'a':2, 'b':3}, Iterator)) #字典不是迭代器
print(isinstance((1, 2, 3), Iterator)) #元组不是迭代器
print(isinstance({1, 2, 3}, Iterator)) #集合不是迭代器
print(isinstance(1, Iterator)) #整数是不是迭代器
运行结果:
False
False
False
False
False
False
通过iter()函数创建迭代器
numb = [1, 2, 3, 4, 5] #创建的是列表,通过iter函数创建就是列表迭代器,如果是集合、字典、字符串那就是集合迭代器、字典迭代器、字符串迭代器;
it = iter(numb)
print(type(it))
运行结果:
<class 'list_iterator'> #列表迭代器
通过next()函数取值
numb = 'hello'
it = iter(numb)
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it))
运行结果: #从第一个元素开始,到遍历完成结束;
h
e
l
l
o
这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。生成器的作用是一边获取一边生成,用多少生成多少;
#推导式生成器
g = (i* i for i in range(4))
print(type(g))
运行结果:
<class 'generator'> #类型为生成器
#通过yield,函数返回值会变成生成器
- 斐波那契数列
def fibonacci(n):
a, b, counter = 0, 1, 0
while True:
if counter > n:
return
yield a
a, b = b, a+b
counter = counter + 1
fib = fibonacci(10)
# print(type(fib))
for i in fib:
print(i, end=',')
运行结果:
<class 'generator'> #print数据类型为生成器
0,1,1,2,3,5,8,13,21,34,55, #直接遍历取出
装饰器定义:装饰器是函数,只不过该函数可以具有特殊的含义,装饰器用来装饰函数或类,使用装饰器可以在函数执行前和执行后添加相应操作完全符合程序开发中,开放-封闭原则;不改变原有代码功能,不改变原有调用方式实现新功能的扩张。
# -*- coding: UTF-8 -*-
# Author: LAIN
# Time: 2018-08-15
#装饰器
user_status = False
def login(fund):
def inner():
user = 'LAIN'
pwd = '12345'
global user_status
if user_status == False:
username = input('USER:')
passwd = input('PASSWORD:')
if username == user and passwd == pwd:
print('登录成功')
user_status = True
else:
print('账号密码错误!')
if user_status == True:
fund()
return inner
def home():
print('-----商城首页-----')
@login #语法糖,表明这是个装饰器
def numerical():
print('-----电子数码-----')
@login
def food():
print('-----食品生鲜-----')
@login
def department():
print('-----百货商品-----')
home()
numerical() #运行login函数后调用
food() #运行login函数后调用
department() #运行login函数后调用