python — 函数基础知识(二)
目录
1 返回值
def func(arg): # .... return 9 # 返回值为9 默认:return none val = func('adsfadsf')
# 1. 让用户输入一段字符串,计算字符串中有多少a字符的个数。有多少个就在文件a.txt中写多少个“李邵奇”。 def get_char_count(data): sum_counter = 0 for i in data: if i == 'a': sum_counter += 1 return sum_counter def write_file(line): if len(line) == 0: return false # 函数执行过程中,一旦遇到return,则停止函数的执行。 with open('a.txt',mode='w',encoding='utf-8') as f: f.write(line) return true content = input('请输入:') counter = get_char_count(content) write_data = "李邵奇" * counter status = write_file(write_data) if status: print('写入成功') else: print('写入失败')
函数没有返回值时,默认返回none。
函数内部执行过程中遇到return就终止。
def func1(): return "完成" # 函数每次执行到此,就返回;所以下面代码永远不执行。 for i in range(10): print(i) func1() def func2(): for i in range(10): print(i) return "完成" print(666) func2() # 只打印0
return可以返回任意值
特殊情况:return返回多个值时,返回的是元组,与返回值是元组时是一样的
def func(): return (1,2,3) v = func() print(v) # 特殊:返回元组 def func(): return 5,8,"alex" v = func() print(v)
return的作用:a. 返回值 b.终止函数的执行
练习题
# 1. 写函数,计算一个列表中有多少个数字,打印: 列表中有%s个数字。 # 提示:type('x') == int 判断是否是数字。 # 方式一: def get_list_counter1(data_list): count = 0 for item in data_list: if type(item) == int: count += 1 msg = "列表中有%s个数字" %(count,) print(msg) get_list_counter1([1,22,3,'alex',8]) # 方式二: def get_list_counter2(data_list): count = 0 for item in data_list: if type(item) == int: count += 1 return count v = get_list_counter1([1,22,3,'alex',8]) msg = "列表中有%s个数字" %(v,) print(msg)
# 2. 写函数,计算一个列表中偶数索引位置的数据构造成另外一个列表,并返回。 # 方式一: def get_data_list1(arg): v = arg[::2] return v data = get_data_list1([11,22,33,44,55,66]) # 方式二: def get_data_list2(arg): v = [] for i in range(0,len(arg)): if i % 2 == 0: v.append(arg[i]) return v data = get_data_list2([11,22,33,44,55,66])
# 3. 读取文件,将文件的内容构造成指定格式的数据,并返回。 """ a.log文件 alex|123|18 eric|uiuf|19 ... 目标结构: a. ["alex|123|18","eric|uiuf|19"] 并返回。 b. [['alex','123','18'],['eric','uiuf','19']] c. [ {'name':'alex','pwd':'123','age':'18'}, {'name':'eric','pwd':'uiuf','age':'19'}, ] """ with open('a.log.txt',mode = 'r',encoding = 'utf-8') as f: data = f.read() print(data) def get_file(a): date1 = [] for i in a.split('\n'): date1.append(i) return date1 v1 = get_file(data) print(v1) def get_file1(b): date2 = [] d = [] for i1 in b.split('\n'): i1 = i1.split('|') d.append(i1) date2 += d return date2 v2 = get_file1(data) print(v2) def get_file2(c): date3 = [] e = {} for i2 in c.split('\n'): i2 = i2.split('|') e['name'] = i2[0] e['pwd'] = i2[1] e['age'] = i2[2] date3.append(e) return date3 v3 = get_file2(data) print(v3)
- 数据类型中的方法到底有没有返回值:
-
无返回值
v = [1,2,3,4] v.append(55) # 无返回值时不用写return了
list : append / insert / remove / clear / extend / reverse
dict : update
set : add / discard / update
-
仅有返回值
v = 'ddff2dd554cvc' result = '-'.join(v) return result v = {'k1':12,'k2':'ased'} result = v.get('k2') result = v.keys()
str : upper / lower / replace / isdecimal / strip / split / startswith / endswith / encode / format / join
list : find / index
dict : keys / values / items / get
set : intersection / union / difference / symmitric_difference
-
有返回值 + 修改数据
pop
v = [11,22,33,44] result = v.pop(22)
-
常用需要记住的
索引、切片都有返回值
str : split 返回列表
strip 返回字符串 replace 返回字符串 join 返回字符串
list : append 无
insert 无 remove 无 pop 返回要删除的数据 find 返回索引的位置 index 返回索引的位置
dict : keys 获取所有的键
values 获取所有的值 items 获取所有的键值对 get 索引存在:返回值 ,不存在:返回none
2 作用域
在python文件中:
py文件:全局作用域
-
函数:局部作用域
a = 1 def s1(): x1 = 666 print(x1) print(a) print(b) b = 2 print(a) s1() a = 88888 def s2(): print(a,b) s1() s2()
-
每个作用域中的数据只有作用域自己可以调用,如果作用域中调用的数据没有,可以调用全局作用域的
全局作用域只能调用全局的
在全局作用域中的函数可以互相调用(调用已经存在的),但不可以直接调用作用域中的作用域
总结:
1.一个函数就是一个作用域
-
2.作用域中查找数据规则:优先在自己的作用域找数据,自己没有就去“父级”-->“父级”-->直到全局,全局没有就报错。 (作用域的嵌套)
注意:父级作用域中的值到底是多少?
x = 10 def func(): x = 9 print(x) func()
小练习
# 示例一 x = 10 def func(): x = 9 print(x) def x1(): x = 999 print(x) func() # 示例二 x = 10 def func(): x = 9 print(x) def x1(): x = 999 print(x) x1() func() # 示例三 x = 10 def func(): x = 9 print(x) def x1(): x = 999 print(x) print(x) x1() func() # 示例四 x = 10 def func(): x = 8 print(x) def x1(): x = 999 print(x) x1() print(x) func() # 示例五 x = 10 def func(): x = 8 print(x) def x1(): print(x) x1() print(x) func() # 示例六 x = 10 def func(): x = 8 print(x) def x1(): print(x) x = 9 x1() x = 10 print(x) func() # 示例七 x = 10 def func(): x = 8 print(x) def x1(): print(x) x1() x = 9 x1() x = 10 print(x) func()
-
3.子作用域中只能只能找到父级中的值,默认无法重新为父级的变量进行赋值。
-
不能进行赋值,只能对可变类型进行内部修改
# ##################### name = 'oldboy' def func(): name = 'alex' # 在自己作用域再创建一个这样的值。 print(name) func() print(name) # ##################### name = [1,2,43] def func(): name.append(999) print(name) func() print(name)
-
如果非要对全局的变量进行赋值需要加global(强制赋值)
#示例一 name = "老男孩“ def func(): global name name = 'alex' func() print name # 示例二 name = ["老男孩",'alex'] def func(): global name name = '我' func() print(name) # 示例三 name = "老男孩" def func(): name = 'alex' def inner(): global name name = 999 inner() print(name) func() print(name)
-
对父级的变量赋值用nonlocal,先找到父级的变量再进行赋值 (强制赋值)
name = "老男孩" def func(): name = 'alex' def inner(): nonlocal name # 找到上一级的name name = 999 inner() print(name) func() print(name)
-
补充:全局变量必须全部要大写
user_list = [11,22,3] def func(): name = 'asdf' user_list.append(12) user_list.append(name) func() print(user_list)
3 函数小高级
-
函数名可以当作变量来使用
def func(): print(123) v1 = func # func代表函数的地址 func() v1() # v1、func的函数地址相同,执行调用的函数也相同
def func(): print(123) func_list = [func, func, func] # func_list[0]() a # func_list[1]() b # func_list[2]() c for item in func_list: # a/b/c的简化形式 v = item() print(v)
def func(): print(123) def bar(): print(666) info = {'k1': func, 'k2': bar} info['k1']() # 函数也可以作为字典的值(也可以做为键,但是没有意义) info['k2']()
注意:函数是不可变的,可以做集合的元素,也可以作为字典的键 (但是做键没有太大意义)。
集合中可以放多个重复的函数,但只执行一次。(因为集合的特性:不可重复的)
混淆你
def func(): return 123 func_list1 = [func,func,func] func_list2 = [func(),func(),func()] print(func_list1) # 打印的是func的函数地址 print(func_list2) # 打印的是func执行完返回的值 info = { 'k1':func, # 函数的地址 'k2':func(), # 函数执行完返回的值 } print(info)
-
函数也可以当作参数来进行传递
def func(arg): print(arg) func(1) func([1,2,3,4]) def show(): return 999 func(show) # 执行函数func,参数为show,show没有+(),表示show没有执行只是代表该函数的地址。
def func(arg): v1 = arg() print(v1) def show(): print(666) func(show)
def func(arg): v1 = arg() print(v1) def show(): print(666) result = func(show) print(result)
多个函数的调用
def func(): print('花费查询') def bar(): print('语音沟通') def base(): print('xxx') def show(): print('xxx') def test(): print('xxx') info = { 'f1': func, 'f2': bar, 'f3':base, 'f4':show, 'f5':test } choice = input('请选择要选择功能:') function_name = info.get(choice) if function_name: function_name() else: print('输入错误')
-
总结:函数当作一个变量:参数传值 / 当作元素嵌套到字典、列表中
4 函数中高级
4.1 函数可以做返回值
# 示例一 def func(): print(123) def bar(): return func v = bar() v() # 示例二 name = 'oldboy' def func(): print(name) def bar(): return func v = bar() v() # 示例三 def bar(): def inner(): print(123) return inner v = bar() v() # 示例四 name = 'oldboy' def bar(): name = 'alex' def inner(): print(name) return inner v = bar() v() # 示例五 name = 'oldboy' def bar(name): def inner(): print(name) return inner v1 = bar('alex') # { name=alex, inner } # 闭包,为函数创建一块区域(内部变量供自己使用,存储的代码),为他以后执行提供数据。 v2 = bar('eric') # { name=eric, inner } v1() v2() # 示例六 name = 'alex' def base(): print(name) def func(): name = 'eric' base() func() # {name=eric, } # 示例七 name = 'alex' def func(): name = 'eric' def base(): print(name) base() func() # 示例八 name = 'alex' def func(): name = 'eric' def base(): print(name) return base base = func() base()
注意:函数在何时被谁创建?
函数是由谁创建的,执行函数就从哪里开始找
# 练习题一 info = [] def func(): print(item) for item in range(10): info.append(func) info[0]() # 练习题二 info = [] def func(i): def inner(): print(i) return inner for item in range(10): info.append(func(item)) info[0]() info[1]() info[4]()
4.2 闭包
def func(name): def inner(): print(name) return inner v1 = func('alex') v1() v2 = func('eric') v2()
返回值——分析函数执行的内存。(闭包是内存其中的一种)
# 并不是闭包 def func(name) def inner(): return 123 return inner # 是闭包需要满足两个条件:1.封装值 2.内层函数需要使用 def func(name) def inner(): print(name) return 123 return inner
4.3 高阶函数
把函数当作参数传递
-
把函数当作返回值
注意:对函数进行赋值
4.4 小总结
- 1.函数执行流程的分析(函数到底是由谁创建的?)
- 2.闭包概念:为函数创建一块区域并为其维护自己的数据以后执行时方便调用。(应用场景:装饰器 / sqlalchemy源码)
下一篇: prisma反向代理