阅读目录

  • 函数基础
    • 基础知识
    • return 返回值
    • 不可变类型和可变类型的值传递问题
    • 函数的参数
    • 打散和聚合
  • 函数进阶
    • 函数的注释
    • 命名空间
    • 作用域和全局变量
    • 函数的嵌套和作用域链
    • 函数名
    • 闭包
  • 函数练习题

函数基础

基础知识

函数概述: 在一个完整的项目中(假设有大量的代码),会有一些需要重复使用的代码,
可以将这些重复的代码写成一个函数,当我们的重复使用的时候,直接调用就可以了本质: 代码的封装优点:1.极大的简化了代码,提高了复用性
2.当代码需要添加,修改功能(bug)时,只需要去对应的位置修改就行了格式:def 函数名(参数1,参数2,...):语句块return 结果/表达式
1.定义一个函数时需要以 def 关键字开始
2.函数名是给该函数取一个名字(自定义),函数名遵循标识符命名规则,见名知意
3.函数名后面是(),()中用来放参数列表,当参数列表为空时,()不能省略,
4.参数列表(形式参数)可以有多个,也可以没有,参数列表中的参数是用来接收参数的,接收参数就是变化的量
5.()后需要跟上 : ,:表示函数体的开始, 函数体需要用Tab健缩进来表示范围
6. 语句块 -- 就是需要重复使用的代码
7.return :1.用来返回一个结果/表达式 , 返回的值是用来告诉调用者的2.return 可以省略,省略就表示不需要返回结果!注意:如果没有写return,默认会执行return None3.return可以用来终止函数, 函数默认是函数体执行完后自动终止调用格式:
函数名(参数1,参数2,...)1.函数名是需要调用的函数的函数名(名字必须一致)
2.函数名后跟(),()中放置需要传递给定义函数的参数(实际参数)
3.()可以是空参, 即使是空参, ()也不能省略本质: 实际参数赋值给形式参数的过程def abacus(a, b):c=a+breturn c
print(abacus(1,2))>>>需求: 通过函数来打印一个语句
# 注意: 函数需要先定义再使用
# printStr() 不能写在上面# 单独定义的函数,是不执行的
def printStr():print("min is a nice man")print("min is a handsome man")print("min is a good man")# 假设第一次调用
printStr()
# 假设第n个地方调用
printStr()函数参数的执行过程:需求: 定义一个函数用来输出姓名,年龄# 定义函数的地方,参数名叫形式参数
# 调用的时候实际参数赋值给形式参数的过程
# 相当于 形式参数name = 实际参数name = "死胖子"
def printNameAndAge(name,age):
# name代表的形式参数变量print("%s的年龄是%d"%(name,age))#print(name)#print(age)
# 调用
printNameAndAge("周杰伦",32) # 可以直接在这里给形式参数赋值name1= "许嵩"
age1= 34 # 也可以重新定义全局变量,先给实际参数传值,然后实际参数会给形式参数传值
# 调用函数的位置,传入的参数叫实际参数
printNameAndAge(name1,age1)# 注意:调用函数时,传入参数的个数需要与定义函数参数的个数一致
printNameAndAge("周杰伦") # 错误,个数不一致# 注意:调用函数时,传入参数的顺序需要以定义时的一致(主要看函数体)
printNameAndAge(78,"林俊杰")#错误,顺序不一致

return 返回值

为什要有返回值?后面其他程序可能需要用到
>>>需求:定义一个函数,求两个数的和def add(a,b):c = a + bfor i in range(10):print("哈哈",i)# return 这里加了return会在i取0时完成后,直接跳到res=add(),然后把一个None给调用者,后面的代码都不执行了return c #如果没写,会默认 return None,也可以写成:return a + bprint("你已经成功计算出结果")#这行不执行# 调用
res = add(100,101) #返回值给了调用者作为结果,即是C
print(res)
1.return 会将一个结果返回,结果会作为调用者的返回值
2.rerurn 可以不写,不写是默认执行return None
3.return后也可以跟表达式,如果是表达式,会先执行表达式,然后将表达式的结果返回
4.注意: return 可以用来终止函数的执行;无论是在判断还是在循环体内,只要满足条件执行到了一次return后,return后的语句不会执行
5.返回值个数:0-None  1-Object(本身)  >1个-tuple(元祖)

不可变类型和可变类型的值传递问题

# 不可变类型:
def editNumber(number): number = 90 print("number的值为:%d"%(number))num = 100
editNumber(num)
print(num) #100
# 上述输出结果:number的值为:90 100
# 实质就是不可变类型,会重新开辟地址指向新地址,所以第二个数会改变# 可变类型:
def editNames(listName):listName[0] = "马伊俐"print(listName)names = ["马蓉","麻花藤","马赛","马云","马克"] # 执行到这里时,不会重新开辟地址,而是直接替换
editNames(names)
print(names) # 最后一步执行# 输出结果:['马伊俐', '马化腾', '马赛克', '马云', '马克思']   ['马伊俐', '马化腾', '马赛克', '马云', '马克思']

函数的参数

  • 关键字参数:
def print_person(name,age,likes):print("名字是:%s"%(name))print("年龄是:%d"%(age))print("他的爱好有:%s"%(likes))print_person("ym",25,["play","movies","world"]) # 不用关键字,需要一一对应print_person(age=25,name="ym",likes=["play","movies","world"]) # 都用了关键字,位置可以乱序,但不能缺失print_person("ym",age=25,likes=["play","movies","world"]) # 用了关键字的需要放在后面
# 注意:关键字参数需要写在参数列表的后面,非关键字参数需要写所有关键字参数前
# 关键字参数的 关键字名 就是 形式参数的变量名
  • 默认值参数:
>>>需求:打印人的姓名,年龄,性别,爱好,身高# def printPerson(name,age,gender,heigth):
# 定义函数的时候可以在形式参数列表的后部给参数设置默认值,设置了下面实际参数可以不写
def printPerson(name,age,heigth = 179,gender = "男"): # 默认值需要放在后面print("name=%s,age=%d,gender=%s,heigth=%d"%(name,age,gender,heigth))# printPerson("周杰伦",36,"不明",160)# 注意:在给函数传递参数的时候,默认值可以不传递,会自动的设置成默认值;
# --如果设置了默认值同时又传递了该参数,则实际传递的值优先级高
printPerson("周杰伦",26,160)# 用处:设置一些默认值
def test(x,soft1=True,soft2=True)print(x)soft.
test()# 参数陷阱
# 如果默认参数是一个可变数据类型
def defult_param(a, l=[]):l.append(a)print(l)defult_param('alex')
defult_param('egon')
'''
结果:
['alex']
['alex', 'egon']
'''
  • 不定长参数(动态参数):
    不定长参数:一个参数表示多个值,也叫“参数组”
>>>需求:求多个数的和 
def addMoreNumber(num1,num2,num3,...100): #这样表示多个时就很麻烦# 用 * 表示的变量,用来接收任意多个没有命名的变量,会自动将这多个变量封装成元组,并传到到函数中
# 如果没有参数,会是一个空的元组
# 最好将可变长参数放在参数列表的后面
def addMoreNumber(name,*args):pass #定义了函数,暂时不用可以写个pass#print(args)#print(type(args))#这里可以看到一个*的是元祖类型print("name=%s"%(name))for i in args:print(i)# 调用
addMoreNumber() # 传空值
addMoreNumber(12) # 传一个值
addMoreNumber(12,23,233,45) # 传多个值
addMoreNumber(12,23,233,45,name = "胖胖胖") # 因为是关键字参数,一一对应,所以上面的函数参数*args,name也行
addMoreNumber("胖胖",12,23,233,45) # 因为是*args放在了后面,所以不用命名关键字参数也行>>>完成:求任意多个数的和
def sum(*args):count=0for i in args:count+=ireturn count
# 调用
res=sum(1,2,3,4) # return 会把值返回来,所有可以用变量来接收
print(res) # 或者写成:print(sum(1,2,3,4))# 用 ** 表示的参数,用来接收任意多个有命名(key-value)的参数,
# --会自动的将多个参数封装成字典, 参数名作为key,值作为value
# 如果没有命名的参数传递,则会生成一个空的字典传递进来
def func(**kwargs):print(kwargs)print(type(kwargs))#for key,value in kwargs.items()# 测试
func() # 不传参数,会生成一个{}空字典
func(age=10,name="周杰伦") # 传有命名的参数(相当于键值对)定义一个通用函数:
def function(*args,**kwargs): # 这样可以传任意类型的参数,一般按照* **顺序
function(34,23,34,name="helo",age ="18") # 有命名的放在后面,放前面会报错
形参的位置顺序: 位置参数,*args,默认值参数,**kwargs
实参只有两种形式:位置参数,关键字参数

打散和聚合

# 形参: 聚合
def func(*food): # 聚合, 位置参数print(food)
lst = ["鸡蛋","煎饼果子","猪蹄","滋滋冒油"]
# func(lst)这是当做一个参数传进去了
# func(lst[0],lst[1],lst[2],lst[3])# 实参: 打散
func(*lst) #打散:把list, tuple, set, str进行迭代打散# 聚合成关键字参数
def func(**kwargs):#关键字参数print(kwargs)# 打散成关键字参数
dic = {"name":'alex', 'age':'18'}
# func(name=dic["name"],age=dic["age"])
func(**dic) 

函数进阶

函数的注释

def func(a, b):"""这个函数是用来计算a和b的和:param a: 第一个数据:param b: 第二个数据:return: 返回的是两个数的和"""return a + b
print(func.__doc__) # document文档

命名空间

在python解释器开始执⾏之后, 就会在内存中开辟⼀个空间,每当遇到⼀个变量的时候,就把变量名和值之间的关系记录下来, 但是当遇到函数定义的时候;解释器只是把函数名读入内存,表⽰这个函数存在了,⾄于函数内部的变量和逻辑,解释器是不关⼼的。
也就是说⼀开始的时候函数只是加载进来,仅此⽽已,只有当函数被调⽤和访问的时候,解释器才会根据函数内部声明的变量来进⾏开辟变量的内部空间,随着函数执⾏完毕;这些函数内部变量占⽤的空间也会随着函数执⾏完毕⽽被清空。
def fun():a = 10print(a)
fun()
print(a) # a不存在了已经def sum_two(n):he=0for i in range(1,n,2):he+=ireturn he#print(he) 已经被清除,显示错误,为定义变量
print(sum_two(10))
print(sum_two(10))
命名空间一共分为三种:全局命名空间局部命名空间内置命名空间

*内置命名空间中存放了python解释器为我们提供的名字:
input,print,str,list,tuple…它们都是我们熟悉的,拿过来就可以用的方法。

三种命名空间之间的加载与取值顺序:加载顺序:内置命名空间(程序运行前加载)->>全局命名空间(程序运行中:从上到下加载)->>局部命名空间(程序运行中:调用时才加载)

取值:
在局部调用:局部命名空间->全局命名空间->内置命名空间

x = 1
def f(x):print(x)print(10)

在全局调用:全局命名空间->内置命名空间

x = 1
def f(x):print(x)f(10)
print(x)print(max) # 在全局中引用内置的max

作用域和全局变量

def fun():b = 110def gun():c = 100print(globals())print(locals())  # c=100gun()fun()
print(globals())  # 可以查看全局作用域的内容
print(locals())  # 查看当前作用域的内容作用域:变量的使用范围
# 注意:程序中的变量不是在任何地方都可以使用的,使用的范围是由定义的位置确定的
# 注意:在python中只有模块,类,函数会引入新的作用域,while,for,if,elif 不会引入新的作用域(即可以共用)def edit_number():number = 100print(number)num = 100 # 函数里定义的,函数外不能使用
number = 99
edit_number()
print(number) # 输出结果:100 99# 在函数外面不能使用函数里面定义的变量
print(num) # 直接报错if True: # 或者 if Flase 下面就不能用这个变量了num = 100
print(num) # 不会引入新的作用域

全局变量:

number = 100def edit_number():# 声名number是全局变量global number  # 拿到外部的变量number=100number = 99print(number) # 99edit_number()
print(number) # 此时的全局变量已经被修改了
'''
输出结果 99 99
不要这样使用,外面或者其他位置都可以使用、修改变量,导致出错
'''>>>练习
def outer():print("哈哈")def inner_1():print("呵呵")def inner_1_1():print("嘻嘻")inner_1_1()print("吼吼")inner_1()def inner_2():print("嘿嘿")inner_2()
# inner_1() 报错,在函数内部的函数,无法直接访问到,未定义错误
outer()  # 哈哈 呵呵 嘻嘻 吼吼

函数的嵌套和作用域链

  • 函数的嵌套调用
def max2(x,y):m  = x if x>y else yreturn mdef max4(a,b,c,d):res1 = max2(a,b)res2 = max2(res1,c)res3 = max2(res2,d)return res3max4(23,-7,31,11)
  • 函数的嵌套定义
# 定义一
def f1():print("in f1")def f2():print("in f2")f2()
f1()
# 定义二
def f1():def f2():def f3():print("in f3")print("in f2")f3()print("in f1")f2()f1()
  • 函数的作用域链
# 作用域链(一)
def f1():a = 1def f2():print(a)f2()f1()
# 作用域链(二)
def f1():a = 1def f2():def f3():print(a)f3()f2()f1()
# 作用域链(三)
def f1():a = 1def f2():a = 2f2()print('a in f1 : ',a)f1()
global 和 nonlocala = 10  # 全局变量本身就是不安全的, 不能随意修改, 需要闭包优化def func():global a  # global作用 1. 可以把全局中的内容引入到函数内部 , 2. 在全局创建一个变量# a = 20a += 10  # a = a+10 这里最终赋值是想修改全局变量a,所有如果没有加global不让修改print(a)func()
print(a)
------
a = 10def outer():a = 2def inner():  # 在inner中改变a的值nonlocal a  # 寻找外层函数中离他最近的那个变量,永远不找最外层的全局变量a = 20inner()outer()# nonlocal关键字注意点:
# 1.外部必须有这个变量
# 2.在内部函数声明nonlocal变量之前不能再出现同名变量
# 3.内部修改这个变量如果想在外部有这个变量的第一层函数中生效

函数名

# 函数名本质上就是函数的内存地址,就是一个变量;也要遵守变量命名规范
a = 10
b = a # 赋值操作
print(b)def func():print("我是一个小小的函数")
a = func
# print(func) 打印出的是一个 函数的内存地址
print(a)func()
a()func = 3
print(func) # 结果是:3a = 10
b = 20
c = 30
lst = [a, b, c]
print(lst)def func1():print("我是1")
def func2():print("我是2")
def func3():print("我是3")lst = [func1, func2, func3]
for el in lst: # 将每个内存地址遍历,然后当做函数调用el()# 函数名可以作为参数传递给函数
def my():print("我是my")def proxy(fn): # 代理模式.装饰器print("在处理之前")fn() #这里写成 my() 也行print("在处理之后")proxy(my) # 把函数名作为参数传递给另一个函数def func1():print("我是func1")def func2():print("我是func2")def func(fn, gn): # 函数名可以作为参数进行传递print("我是func")fn()gn()print("哈哈哈")
func(func1, func2)# 函数名可以做为返回值
def func():print("我是func")a = 10 #变量def inner():print("我是inner")return inner
#ret = func()
#ret()
func()() # 先运行func(),然后在返回值上加()# 拓展:
def func():print("我是func")a = 10 # 变量def inner():print("我是inner")return inner,a
print(func()[1]) # 结果是:10
# 有两个返回值时,会把一个元组返回给函数tu=func()
tu[0]() # 调用 inner()
print(tu[1]) # 10

闭包

闭包:在内层函数中访问外层函数的变量;或者描述为:内部函数包含对外部作用域而非全局作用域名字的引用,该内部函数称为闭包函数函数内部定义的函数称为内部函数
闭包的作用:1. 可以保护变量不受侵害2. 可以让一个变量常驻内存

a = 10 # 不安全的,只要函数里用到了,且重新赋值后,值都会改变
def outer():global aa = 20def outer_2():global aa = 30outer_2() # 30
outer() # 20
print(a) # 20 # 任何位置都可以修改a# 闭包优化
def outer():a = 10  # 对外界不开放;常驻内存,为了inner执行的时候有值def inner():nonlocal aa=20  # 只能内部修改print(a)return inner # 注意是外层函数,返回内层函数的函数名
fn = outer() # 此时的fn就是 inner# print("fdsafasd")
# print("fdsafasd")
# print("fdsafasd")fn() # 调用的时机是不定的# 拓展分析:
def outer():a = 10  # 对外界不开放;常驻内存,为了inner执行的时候有值print(a)def inner():nonlocal a # 不用nonlocal 内层的a也有值,因为常驻内存了a = 30  # 只能内部修改print(a)return inner
fn = outer() # inner
fn()  # 调用的时机是不定的
outer() # 再调用一次,结果发现外层函数的a在nonlocal下也没有被改变# 输出结果为:10 30 10>>>简易爬虫,如何用到闭包from urllib.request import urlopendef outer():s = urlopen("http://www.zhuixinfan.com/main.php?mod=viewall&action=tvplay&alpha=n").read()# 常驻内存def getContent():  # 闭包return sreturn getContentprint("爬取内容.....")
pa = outer()ret = pa()
print(ret)ret = pa()
print(ret)ret = pa()
print(ret)# 查看是否是闭包
def func():a = 10def inner():print(a)  # 用了外层函数变量,就是闭包# print("没用你外层变量")print(inner.__closure__)  # 如果打印的是None,不是闭包;如果不是None,就是闭包# 输出的__closure__有cell元素 :是闭包函数func()
命名空间:一共有三种命名空间从大范围到小范围的顺序:内置命名空间、全局命名空间、局部命名空间作用域(包括函数的作用域链):小范围的可以用大范围的
但是大范围的不能用小范围的
范围从大到小(如图)

在小范围内,如果要用一个变量,是当前这个小范围有的,就用自己的
如果在小范围内没有,就用上一级的,上一级没有就用上上一级的,以此类推。
如果都没有,报错

函数的嵌套:

嵌套调用嵌套定义:定义在内部的函数无法直接在全局被调用

函数名的本质:

就是一个变量,保存了函数所在的内存地址

闭包:

内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数
  • 深入理解闭包

(1)函数的引用

def test1():print("--- in test1 func----")# 调用函数
test1()# 引用函数
ret = test1print(id(ret))
print(id(test1))#通过引用调用函数
ret()# 运行结果
--- in test1 func----
140212571149040
140212571149040
--- in test1 func----

(2)闭包

# 定义一个函数
def test(number):# 在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包def test_in(number_in):print("in test_in 函数, number_in is %d" % number_in)return number+number_in# 其实这里返回的就是闭包的结果return test_in# 给test函数赋值,这个20就是给参数number
ret = test(20)# 注意这里的100其实给参数number_in
print(ret(100))#注 意这里的200其实给参数number_in
print(ret(200))# 运行结果
in test_in 函数, number_in is 100
120in test_in 函数, number_in is 200
220

(3)闭包实例

def line_conf(a, b):def line(x):return a*x + breturn lineline1 = line_conf(1, 1)
line2 = line_conf(4, 5)
print(line1(5))
print(line2(5))# 运行结果

这个例子中,函数line与变量a,b构成闭包。在创建闭包的时候,我们通过line_conf的参数a,b说明了这两个变量的取值,这样,我们就确定了函数的最终形式(y = x + 1和y = 4x + 5)。我们只需要变换参数a,b,就可以获得不同的直线表达函数。由此,我们可以看到,闭包也具有提高代码可复用性的作用。

如果没有闭包,我们需要每次创建直线函数的时候同时说明a,b,x。这样,我们就需要更多的参数传递,也减少了代码的可移植性。

注意点: 由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存

(4)修改外部函数中的变量

# python3中的方法def counter(start=0):def incr():nonlocal startstart += 1return startreturn incrc1 = counter(5)
print(c1())
print(c1())c2 = counter(50)
print(c2())
print(c2())print(c1())
print(c1())print(c2())
print(c2())
# python2 中def counter(start=0):count=[start]def incr():count[0] += 1return count[0]return incrc1 = closeure.counter(5)
print(c1())  # 6
print(c1())  # 7
c2 = closeure.counter(100)
print(c2())  # 101
print(c2())  # 102

函数练习题

>>>写函数,计算传入字符串中单个【数字】、【字母】、【空格】 以及 【其他】的个数
# 方法一:
s.isalnum() 所有字符都是数字或者字母,为真返回 Ture,否则返回 False。s.isalpha() 所有字符都是字母,为真返回 Ture,否则返回 False。s.isdigit() 所有字符都是数字,为真返回 Ture,否则返回 False。s.islower() 所有字符都是小写,为真返回 Ture,否则返回 False。s.isupper() 所有字符都是大写,为真返回 Ture,否则返回 False。s.istitle() 所有单词都是首字母大写,为真返回 Ture,否则返回 False。s.isspace() 所有字符都是空白字符,为真返回 Ture,否则返回 False。def str_number(str_num):count = 0count2 = 0count3 = 0count4 = 0for i in str_num:if i.isdigit() == True:count += 1elif i.isalpha() == True:count2 += 1elif i.isspace() == True:count3 += 1else:count4 += 1print("数字有%d个"%count)print("字母有%d个"%count2)print("空隔有%d个"%count3)print("其它有%d个"%count4)#return(count,count2,count3,count4),用不用括号都行#str_num = input("请输入:")
#str_number(str_num)
str_number(input("请输入:"))# 方法二:ord()函数
# ord()函数是chr()函数(对于8位的ASCII字符串)或unichr()函数(对于Unicode对象)的配对函#--数,它以一个字符(长度为1的字符串)作为参数,返回对应的 ASCII 数值,或者Unicode数值,#--如果所给的Unicode字符超出了你的Python定义范围,则会引发一个TypeError的异常# 格式:ord(c) c是字符
>>>ord('a')
97
>>> ord('b')
98
>>> ord('c')
99def strInNumber(str):number=0#数字letter=0#字母blank=0#空格other=0#其他for i in range(0,len(str)):# 判断字符是否为数字if ord(str[i])>=48 and ord(str[i])<=57:number+=1# 判断字符是否为字母elif (ord(str[i])>65 and ord(str[i])<=90) or (ord(str[i])>=97 and ord(str[i])<=122):letter+=1# 判断字符是否为空格elif ord(str[i])==32:blank+=1else:other+=1print("该字符串中数字有%d个,字母%d个,空格%d个,其他的%d个." % (number, letter, blank, other))
# return number,letter,blank,other
strInNumber(input("请输入内容:"))
>>>写函数,判断用户传入的参数(字符串、列表、元组)长度是否大于5
# 方法一:
def judge_len(str,list,tuple):if len(str)>5:print("yes")else:print("No")if len(list)>5:print("yes")else:print("No")if len(tuple)>5:print("yes")else:print("No")return len(str),len(list),len(tuple)count=judge_len("kwkwqehk",[11,22,33],(1,"215",5,6,59,6))
print(count)# 方法二:
def judge_enter(*args):length=0for i in args: #for i in range(len(args))length+=1if length>5:print("yes")else:print("no")return lengthprint(judge_enter("kwkwqehk")) # 会把字符串默认成元祖,只能传数字?
>>>写函数,检查用户传入的对象(字符串、列表、元组)的每一个元素是否含有空内容。
# 方法一:
def check_enter(n):if len(n) == 0:print("have")else:for i in n:if i == None or i =="":print("have")else:print("no")
check_enter(("","qefafasf"))# 方法二:
def check_use(args):res = True # 检测作用for i in args:if i.isspace():res = False # 加这个只是看下是否执行break # break是直接跳出最外围的for循环,不用去判断后面的每一个元素了return resresult = check_use("123 12312")
print("输入内容有空格",result)
>>>写一个函数,识别字符串是否符合python语法的变量名
# 方法一:
import keywordkey_word = keyword.kwlistdef judge_grammar(enter):# 当输入为空,或者退出指令if enter == "exit" or enter == "":print("输入不合法,请重新输入")else:for i in enter:  # 遍历字符串if enter[0].isalnum() or enter[0] == "_":  # 判断第一个元素是否为字母或者数字、下划线if enter[0].isdigit() or enter in key_word:  # 筛选掉开头为数字和关键字的print("输入不合法,请重新输入")break  # 只能用于循环内else:  # 反之都不符合print("输入不合法,请重新输入")breakprint("输入符合语法")  # 这句放在if判断外break  # 只让它输出一次enter = input("请输入:")
judge_grammar(enter)# 方法二:
import keywordkey_word = keyword.kwlistdef python_grammar(num):# 判断输入的空字符if num == "":print("不符合python命名规则")returncount = 0while count < len(num):# 判断字符串的所有字符都是数字或字母或下划线"_"if (num[count].isalnum() == True) or (num[count] is "_"):# 判断是否为关键字if num in key_word:print("不符合python命名规则")return# 判断开头第一个字符是否为数字elif num[0].isdigit() == True:print("不符合python命名规则")returnelse:print("不符合python命名规则")return# 计数器count += 1# 都判断完剩下都是符合了print("符合python命名规则")name = input("输入一个字符串:")
python_grammar(name)
>>>定义一个函数,输入不定个数的数字,返回所有数字的和
def sum(*args):add = 0for i in args:add = add + ireturn add# enter=int(input("please enter some numble:"))
# print(sum(enter))print(sum(1, 2, 3))
>>>写函数,传入一个参数n,返回n的阶乘
# range(start, stop,step)
def cal(n):res = 1for i in range(n, 0, -1):  # 倒序res = res * ireturn resprint(cal(3))
>>>函数打印第n个菲波那切数列是几?(兔子公式)
def fibonaqie(n):if n == 0:return 0if n == 1:return 1if n > 1:return fibonaqie(n - 2) + fibonaqie(n - 1)print(fibonaqie(5))
>>>写个字符串,通过遍历的方式计算字符串的长度
def jlen(str):x = 0for i in str:x += 1print(u'该字符串的长度为:', x)return xjlen('xiegezifuchuan')>>>写入不定个数的字符串拼接第一个和最后一个字符串
def splicing(*args):return args[0] + args[-1]print(splicing('1', '2', '3'))>>>传入多个参数,以list返回
def returnlist(*args):li = []for i in args:li.append(i)return liprint(returnlist(1, 2, 3, 4))>>>任意输入年月日,计算出这是这一年的哪一天from functools import reduce
year = int(input('year:\n'))
month = int(input('month:\n'))
days = int(input('days:\n'))months = [0,31,28,31,30,31,30,31,31,30,31,30]
leap_moths = [0,31,29,31,30,31,30,31,31,30,31,30]def de_leap(year):if (year % 400 == 0) or (year % 4 == 0) and (year % 100 != 0):return Trueelse:return Falseif de_leap(year):sum = reduce(lambda x,y:x+y,leap_moths[:month])+int(days)print("这是第%d天"%sum)else:sum = reduce(lambda x, y: x + y, months[:month]) + int(days)print("这是第%d天" % sum)
>>>实现一个写日记的功能,内容需要包含:时间+内容import timedef write_log():time_format = "%Y-%m-%d %X"time_current = time.strftime(time_format)with open("testlog.txt", "a+", encoding="utf-8") as log_file:log_file.write("%s 写入的内容\n" % (time_current))def write1():print("在第一个函数中调用")write_log()def write2():print("在第二个函数中调用")write_log()def write3():print("在第三个函数中调用")write_log()# 调用
write1()
write2()
write3()# 写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,
# 并将其作为新列表返回给调用者。li = ["min", "we", "get", "jie", "like"]  # 外部def check(a):lis = []for i in range(len(a)):  # 这里的a改成li也行if i % 2 == 1:lis.append(a[i])return lisres = check(li)
print(res)# 优化:
li = ["min", "we", "get", "jie", "like"]def check(a):return a[1::2]print(check(li))# 写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于5
def check(a):return len(a) > 5print(check("这段代码很少哦"))# 写函数,检查传入列表的长度,如果大于2,将列表的前两项内容返回给调用者
li = ["min", "we", "get", "jie", "like"]def check(a):if len(a) > 2:return a[:2]print(check(li))
>>>写函数,计算传入函数的字符串中,数字、字母、空格 以及 其他内容的个数,并返回结果
def count(a=""):num = 0aph = 0speace = 0other = 0for i in a:if i.isdigit():num += 1elif i.isalpha():aph += 1elif i.isspace():speace += 1else:other += 1return num, aph, speace, otherprint(count(input("please enter str:")))
>>>写函数,接收两个数字参数,返回比较大的那个数字
def against(a, b):return a if a > b else b  # 中间是运算,两边是结果取的值print(against(6, 2))def against(a, b):return a if a > b else bprint(against(int(input("num1:")), int(input("num2:"))))
>>>写函数,检查传入字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
# dic = {"k1": "v1v1", "k2": [11,22,33,44]}dic = {"k1": "v1v1", "k2": [11, 22, 33, 44]}def cut(a):new_dic = {}for key, value in a.items():if len(value) > 2:new_dic[key] = value[:2]else:new_dic[key] = valuereturn new_dicprint(cut(dic))
>>>写函数,此函数只接收一个参数且此参数必须是列表数据类型,
# 此函数完成的功能是返回给调用者一个字典,
# 此字典的键值对为此列表的索引及对应的元素。
# 例如传入的列表为:[11,22,33] 返回的字典为 {0:11,1:22,2:33}li = [11, 22, 33, 44]def change(a):if type(a) == list:dic = {}for i in range(len(a)):dic[i] = a[i]return dicelse:return "不是列表"print(change(li))
>>>写函数,函数接收四个参数分别是:姓名,性别,年龄,学历。
# 用户通过输入这四个内容,然后将这四个内容传入到函数中,
# 此函数接收到这四个内容,将内容追加到一个student_msg文件中。def func(name, age, edu, gender="男"):with open("student_msg", mode="a", encoding="utf-8") as f:f.write(name + "_" + gender + "_" + age + "_" + edu + "\n")  # 处理数据好习惯name = input("please enter your name:")
age = input("please enter your age:")
edu = input("please enter your education:")
gender = input("please enter your gender:")print(func(name, age, edu, gender))# 要求,不断让用户录入,如果没有写姓名,则默认为男
def func(name, age, edu, gender="男"):with open("student msg.txt", mode="a", encoding="utf-8") as f:f.write(name + "_" + gender + "_" + age + "_" + edu + "\n")while True:content = input("enter Q quit:")if content.upper() == "Q":breakname = input("please enter your name:")age = input("please enter your age:")edu = input("please enter your education:")gender = input("please enter your gender:")if gender == "":func(name, age, edu)
else:func(name, age, edu, gender)
>>>求下面函数,最终打印效果:
a = 1  # global后变成了3def fun_1():a = 2def fun_2():global a  # 只改变最外层的a,上一层的a不变a = 3def fun_3():a = 4print(a)print(a)fun_3()print(a)print(a)fun_2()print(a)  # 2print(a)
fun_1()
print(a)  # 3
# 1 2 3 4 3 2 3a = 1  # global后变成了3def fun_1():a = 2  # a=3def fun_2():nonlocal a  # 只改变临近有变量的一层 a=2a = 3def fun_3():a = 4print(a)print(a)fun_3()print(a)print(a)fun_2()print(a)print(a)
fun_1()
print(a)# 1 2 3 4 3 3 1
>>>写一个函数,传入n个值,求它们的和
def sumnum(*args):res = 0for i in args:res += ireturn resa = (1, 2, 3, 4)
print(sumnum(*a))  # 打散print(sumnum(1, 2, 3, 4))# 优化:
def sumnum(*args):return sum(args)a = (1, 2, 3, 4)
print(sumnum(*a))# sum求和函数:
# 可以直接接受一个可迭代对象. 他会把这个可迭代对象进行迭代. 把每个元素累加
>>>求下面函数的结果:
a = 10
b = 20def test5(a, b):print(a, b)return print(a, b)  # 也返回 Nonec = test5(b, a)
print(c)# 20,10,None
print()
#只打印显示内容,不会有什么返回内容,所以是Nonea = 10
b = 20def test5(a, b):a = 3b = 5print(a, b)  # 10 20
c = test5(20, 10)
print(c)  # None
print(a, b)  # 10, 20# 将多个可迭代打散传入到函数的形参中去
def func(*args):print(args)func(1, 4, 7, 9, "你", "好", "啊")
func(*[1, 4, 7, 9], *"你好啊")# 分析
def wrapper():a = 1def inner():# nonlocal a# global a  a += 1  # 这里赋值运算会去改变全局变量,是不被允许的,所以会报错print(a)inner()wrapper()>>>传入两个数,将较小的数返回
def max_num(a, b):return a if a < b else bprint(max_num(4, 2))
>>>传入一个参数(可迭代对象),用“_”将每一个元素连接起来,然后输出
def join_str(lis):s = ""for el in lis:s = s + str(el) + "_"# return s.strip("_")return s[:len(s) - 1]li = [1, "min", "max"]  # 不能用.join的原因,里面必须全是字符串元素
print(join_str(li))def join_str(lis):new = []for el in lis:new.append(str(el))return "_".join(new)  # 就要用.joinli = [1, "min", "max"]
print(join_str(li))
>>>比较传入多个数的最大值和最小值,并以字典形式输入
def against(*args):dic = {}dic["max"] = max(args)dic["min"] = min(args)return dic# 直接写一行也行return {"max": max(args), "min": min(args)}num = (1, 5, 6, 7)
print(against(*num))>>>传入一个数字n,返回它的阶乘
def more(n):s = 1i = 1while i <= n:s *= ii += 1return sprint(more(4))# 法二:倒序优化def more(n):s = 1while n >= 1:s *= nn -= 1return sprint(more(4))# 法三:for循环def more(n):s = 1for i in range(1, n + 1):s *= ireturn sprint(more(4))
# 当然也可以用递归>>>输出一副扑克牌
def ace(num, colour=["红心", "黑桃", "方块", "梅花"]):res = []for el in colour:for i in range(1, num + 1):res.append((el, i))return resprint(ace(13))>>>添加代码用两种或以上的方法执行到 inner()def wrapper():def inner():print(666)inner()wrapper()# 第二种:返回函数名def wrapper():def inner():print(666)return inner  # 函数名res = wrapper()  # 此时接收到的是个函数
res()  # 函数的调用;函数名 加()就是调用函数
# 可以写成 wrapper()()
# print res# 第三种:多层嵌套def wrapper():def inner():print(666)def fun():inner()fun()wrapper()# 第四种:# 函数默认值如果是可变类型,则不会使用新的
def extendList(val, list=[]):  # 默认值如果是可变的数据类型. 每次使用的时候都是同一个print(id(list))list.append(val)return listlist1 = extendList(10)
list2 = extendList(123, [])  # 这个没使用默认值
list3 = extendList('a')print('list1=%s' % list1)
print('list2=%s' % list2)
print('list3=%s' % list3)# 结果:
2321789466120
2321789465032
2321789466120list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']
>>>定义函数打印99乘法表# 传入两个参数
def num(first, second):for i in range(1, first + 1):for j in range(1, second + 1):if i >= j:print("%d*%d=%d" % (j, i, j * i), end=" ")print()num(9, 9)# 优化,只需要传入一个参数
def num(first):for i in range(1, first + 1):for j in range(1, i + 1):  # 遍历行号,就是个数print("%d*%d=%d" % (i, j, j * i), end=" ")print("")num(9)>>>升级题:打印一个‘三角形’
n = 4
for i in range(1, n + 1):for k in range(2 * n - 2 * i):print("", end=" ")for j in range(2 * i - 1):print("*", end=" ")print()
# 分析:* * * ** * * * * * * * * * * * 6
4
2
0等差数列:6 +(n - 1)*2
8 - 2
n8 - 2 * i
2 * n - 2 * i
>>>注册和登录系统,校验
def register():print("欢迎登录注册系统:")while True:user_name = input("please enter your register user name:").strip()pwd = input("please enter your register password:").strip()if user_name == "" or pwd == "":print("your enter content illegal,please try again!")continuewith open("user_info.txt", "r+", encoding="utf-8")as f:for line in f:if line.split("@@")[0] == user_name:print("user name already exists ,please enter new user name!")breakelse:print("congratulations regin succeed!")f.write("\n" + user_name + "@@" + pwd)breakprint("please login next!")i = 1while i <= 3:user_name = input("please enter your user name:")pwd = input("please enter your password:")with open("user_info.txt", "r", encoding="utf-8")as f:for line in f:if line.split("@@")[0] == user_name and line.split("@@")[1] == pwd:print("congratulations login succeed!")returnelse:print("your enter user nmae or password wrong,please try again!")if i > 3:print("your count is frozen!")returni += 1register()
>>>模拟一个购物功能goods = [{"name": "电脑", "price": 1999},{"name": "鼠标", "price": 10},{"name": "美女", "price": 50},{"name": "游艇", "price": 20},{"name": "火箭", "price": 250},
]fei_yong = 0
shop_car = {}  # 键 == 列表的索引;值==商品的数量money = input("请输入您的金额:")if money.isdigit():# 这是真钱while True:# 商品展示:for i in range(len(goods)):print(i + 1, goods[i]["name"], goods[i]["price"])choose = input("请输入你要购买商品的序号(选购完成后,输入N/结算--Q/退出):")# 让用户输入商品序号并判断是不是数字以及在不在正常输入范围内if choose.isdigit() and 0 < int(choose) <= len(goods):# 通过用户输入的内容-1 获取到goods的索引int_index = int(choose) - 1if shop_car.get(int_index) == None:  # 让用户把商品加入到购物车中shop_car[int_index] = 1  # shop_car[0]=1else:shop_car[int_index] = shop_car[int_index] + 1  # 商品数量elif choose.upper() == "N":  # 结算功能for f in shop_car:fei_yong = fei_yong + shop_car[f] * goods[f]["price"]if int(money) - fei_yong >= 0:for k in shop_car:print("您购买的商品是:%s,单价是:%d,数量是:%d" % (goods[k]["name"], goods[k]["price"], shop_car[k]))else:print("余额不足")elif choose.upper() == "Q": \# 退出print(f"您此共消费{fei_yong},剩余金额{int(money) - fei_yong}")breakelse:print("输入有误,请按提示进行输入")
else:# 给了假钱print("请输入正确!")>>>模拟一个购物功能新思路:
def buy():print("购买成功")
def order():print("订单详情")
def back():print("退货成功")def shopping():while True:li=[("购物",buy),("订单",order),("退货",back)]for index,content in enumerate(li,1):print(index,content[0])num=int(input("请选择要执行操作对应的数字:"))try:li[num-1][1]()except:print("请重新输入对应的功能数字!")shopping()
>>>求(x,y)其中x是0-5之间的偶数,y是0-5之间的奇数,组成的元组列表li = [(x, y) for x in range(0, 5, 2) for y in range(0, 5) if y % 2 == 1]
print(li)>>>将M变成[3,6,9] 和 将[3,6,9]变成M
M = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]print([i[2] for i in M])# [3, 6, 9]
print([[i - 2, i - 1, i - 0] for i in [3, 6, 9]])# 构建一个列表:[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
li = [(i, i + 1) for i in range(6)]
print(li)>>>将lst = ['alex', 'WuSir', '老男孩', '太白'] 变成 ['alex0', 'WuSir1', '老男孩2', '太白3']
lst = ['alex', 'WuSir', '老男孩', '太白']
li = [v + str(index) for index, v in enumerate(lst)]  # 枚举
print(li)
# 普通做法:
li = [lst[i] + str(i) for i in range(len(lst))]
print(li)  # 别引入两个未知数,不然是笛卡尔积类型# 将下面的字典
x = {'name': 'alex','Values': [{'timestamp': 1517991992.94,'values': 100, },{'timestamp': 1517992000.94,'values': 200, },{'timestamp': 1517992014.94,'values': 300, },{'timestamp': 1517992744.94,'values': 350},{'timestamp': 1517992800.94,'values': 280}], }li = []
for dic in x.get("Values"):  # x["Values"]ls = []for i in dic.values():ls.append(i)li.append(ls)
print(li)# 规则的数据才能这么做
li = [[dic["timestamp"], dic["values"]] for dic in x.get("Values")]# li = [ [el['timestamp'],el['values']]  for el in x['Values']]
print(li)

Python 函数基础与进阶 闭包 聚合与打散相关推荐

  1. 第三章 Python函数基础及进阶

    第三章 函数基础及进阶 3.1 上章补充内容 3.1.1 Bytes类型 计算机的数据需要存到硬盘上,但是硬盘只能存储二进制的数据. 我们知道将计算机里的数据转换成我们能看懂的数据是将二进制 -> ...

  2. Python函数基础教程-张明阳-专题视频课程

    Python函数基础教程-730人已学习 课程介绍         通过本次课程的讲解,可以让大家对Python函数章节中的装饰器.闭包.函数对象.迭代器和生成器进行彻底的了解,在授课的过程中,将会结 ...

  3. python必备基础代码-新手上路必学的Python函数基础知识,全在这里了(多段代码举例)...

    原标题:新手上路必学的Python函数基础知识,全在这里了(多段代码举例) 导读:函数是Python中最重要.最基础的代码组织和代码复用方式.根据经验,如果你需要多次重复相同或类似的代码,就非常值得写 ...

  4. Python函数基础练习

    Python函数基础练习 1. 输入一行字符,统计其中有多少个单词,每两个单词之间以空格隔开,并将输入字符按首字母大写居中,每个单词首字母大写左对齐,全小写,全大写右对齐的方式分别输出.如输入: Th ...

  5. python零基础学习书-Python零基础到进阶必读的书藉:Python学习手册pdf免费下载

    提取码:0oor Google和YouTube由于Python的高可适应性.易于维护以及适合于快速开发而采用它.如果你想要编写高质量.高效的并且易于与其他语言和工具集成的代码,<Python学习 ...

  6. python函数基础

    函数基础 函数的作用 函数就是包裹一部分的代码,实现某一个功能,达成某一个目的,而且当这段代码如果使用或者重复使用的时候,只需要很简单的调用即可,大大减少了代码的维护难度. 函数的特点 可以反复调用, ...

  7. 【RF基础】RF调用python函数基础

    文章目录 构建 运行 本文简单介绍了如何在robot里面调用一个python写的函数. 构建 我们在D盘下创建两个文件,一个叫pyfile.py,用于编写python函数,另外一个叫test.txt, ...

  8. robotframework调用python类方法_【RF基础】RF调用Python函数基础

    本文简单介绍了如何在robot里面调用一个python写的函数. 构建 我们在D盘下创建两个文件,一个叫pyfile.py,用于编写python函数,另外一个叫test.txt,编写我们的测试用例. ...

  9. Python函数基础3 函数对象、名称空间、装饰器

    今日内容 1.函数对象 2.名称空间与作用域 3.函数的嵌套调用与闭包 4.装饰器 一.函数对象 1.1 定义 函数名存放的就是函数地址,所以函数名也就是对象,称之为函数对象 1.2 函数对象的应用 ...

最新文章

  1. Git命令配置学习笔记
  2. CCNet 的 Build 流程
  3. es6 语法 (Promise)
  4. 关于hibernate的实体类中有集合类型转化成JSON的工具类 - 怀念今天的专栏 - 博客频道...
  5. (3)数据库的建立和数据表的操作
  6. 进阶指南:如何编写可重用程序
  7. 百度时间显示_文章的发布时间对百度优化网站重要吗
  8. 一枚戒指,一场仪式,这件事阿里巴巴坚持了15年
  9. 结构与表现分离的思想
  10. python网络编程(进程与多线程)
  11. 【CSDN软件工程师能力认证学习精选】SQL语句查询
  12. HAL库配置STM32F1系列PWM驱动步进电机(一)
  13. iTop-4412精英版的u-boot-2017.11移植教程(三)
  14. navigationController中navigationBar 的设置
  15. FZU 2214 Knapsack problem
  16. adb按键精灵_自动点击器adb版最新版下载|自动点击器adb版安卓版下载 v1.0.5 - 跑跑车安卓网...
  17. wdcp-apache配置错误导致进程淤积进而内存吃紧
  18. 快速了解iframe框架:
  19. Linux安装和使用FTP服务Serv-U
  20. 【HTML】HTML作业----实现Windows计算器

热门文章

  1. 精简指令集-RISC
  2. 内网穿透常见方式推荐
  3. 商业决策优化求解器软件,继芯片与操作系统之后的国之重器
  4. C语言程序设计 现代方法(第2版)电子书pdf下载
  5. plist解密_免费解密工具针对ThiefQuest Mac勒索软件
  6. 以下描述java字符串错误的是_浙江理工大学java题库
  7. 网上确认审核不通过27个原因,请避开!
  8. 【PHP】实现在地址栏输入信息
  9. ET加密锁外壳保护-高强度保护各种应用程序和数据文件
  10. 客流统计大揭秘——双目客流统计