python函数详解

@[toc]

1. 三元运算
1.1 语法结构
v = 前面 if 条件 else 后面
等价于:
if 条件:
    v = 前面
else:
    v = 后面
1.2 三元运算示例

① 让用户输入一个值,如果值是整数,则转换成整数,否则赋值为None

# coding:utf-8
'''
让用户输入一个值,如果值是整数,则转换成整数,否则赋值为None
'''
data = input('请输入一个值:')
if data.isdigit():
    value = int(data)
else:
    value = None
print(value)
'''
请输入一个值:666
666
'''
2. 面向过程与函数式编程
2.1 面向过程
# coding:utf-8
role_name = input('请输入你的角色:')
if role_name == '管理员':
    pass
if role_name == '业务员':
    pass
if role_name == '……':
    pass
if role_name == '……':
    pass

pass部分是实现发送邮件的一系列逻辑代码,不管是管理员、业务员还是其他角色的人均需要使用到这样重复代码的功能。这种面向过程的编程方式,导致代码的可读性差、可重用性降低。

2.2 函数式编程

使用面向函数编程,会在一定程度上使代码可读性好、可重用性增加。

def send():
    pass
role_name = input('请输入你的角色:')
if role_name == '管理员':
    send()
if role_name == '业务员':
    send()
if role_name == '……':
    send()
if role_name == '……':
    send()

代码重复重复执行、代码量特别多超过一屏,可以选择使用函数进行代码的分割。

3. 函数
3.1 函数的结构
# coding:utf-8
# 函数的定义
def 函数名():
    pass
3.2 函数的执行(重要)

函数执行时,会创建一块内存保存自己函数执行的信息(可由此引出闭包)。函数每被执行一次就会开辟新的内存,每一次执行的函数之间互不干扰。

3.3 函数面试相关

函数如果不被调用,则内部代码永远不会被执行

# 函数的执行
函数名()

函数如果不被调用示例:

func_list = []
for i in range(10):
    func_list.append(lambda: x)  # 函数不被调用,内部永远不执行

print(func_list)
'''
[ at 0x0000026298C1C1E0>,  at 0x0000026298DCC7B8>,  at 0x0000026298DCC8C8>,  at 0x0000026298DCC840>,  at 0x0000026298DCC950>,  at 0x0000026298DCC9D8>,  at 0x0000026298DCCA60>,  at 0x0000026298DCCAE8>,  at 0x0000026298DCCB70>,  at 0x0000026298DCCBF8>]
'''

函数如果被调用示例:

func_list = []
for i in range(10):
    func_list.append(lambda: i)  # 函数不被调用,内部永远不执行

func_list[0]()
func_list[1]()
func_list[2]()
func_list[3]()
func_list[4]()
func_list[5]()
func_list[6]()
func_list[7]()
func_list[9]()
4. 函数的参数
4.1 函数的参数
# coding:utf-8
def get_list_data(data): # data是形式参数(形参)
    lst = ['thanlon', 'kiku']
    print(lst[data])
    
print(get_list_data(0)) # 0是实际参数(实参)
print(get_list_data(1)) # 1是实际参数(实参)

练习1:写一个函数,函数计算指定列表[11,22,33,44,55]中所有元素的和

# coding:utf-8
'''
写一个函数,函数计算指定列表[11,22,33,44,55]中所有元素的和
'''
def sum_list_item():
    lst = [11, 22, 33, 44, 55]
    sum = 0
    for item in lst:
        sum += item
    print(sum)

sum_list_item()
'''
165
'''

练习2:写一个函数,函数计算制定列表种所有元素的和

# coding:utf-8
'''
写一个函数,函数计算制定列表种所有元素的和
'''
def sum_list_item(lst):
    sum = 0
    for item in lst:
        sum += item
    print(sum)

sum_list_item([11, 22, 33, 44, 55])
'''
165
'''

练习3:写一个函数,函数将两个列表拼接起来

# coding:utf-8
'''
写一个函数,函数将两个列表拼接起来
'''
def sum_list_item(lst1, lst2):
    lst = []
    lst.extend(lst1)
    lst.extend(lst2)
    print(lst)

sum_list_item([11, 22, 33, 44, 55], [66, 77, 88, 99])
'''
[11, 22, 33, 44, 55, 66, 77, 88, 99]
'''

练习4:计算一个列表的长度

# coding:utf-8
'''
计算一个列表的长度
'''
def my_lenth(arg):
    count = 0
    for item in arg:
        count += 1
    print(count)
my_lenth([11, 22, 33, 44, 55])
'''
5
'''
4.2 面试题:函数的参数传递的是什么

函数的参数传递的是什么?

'''
函数的参数传递的是什么?
函数的参数传递的是内存地址
'''
v = [1, 2, 3]

def fun(args): # args也指向v的地址,说引用
    print(id(args))  # 列表的内存地址

fun(v)
print(id(v))  # 列表的内存地址
'''
1602601902664
1602601902664
'''
4.3 函数参数的传递

① 参数传递概念
参数可以传任意个数,可以是任意类型。实际参数要与形式参数个数一致,不能多,也不能少。函数

② 位置传参(执行)
实参与形参按照位置顺序一次对应

def func(a1, a2):
    pass
func(1, 2)

③ 关键字传参(执行)
采用关键字传参,参数位置可以调整,根据关键字名

def func(a1, a2):
    pass
func(a1=1, a2=2)

④ 位置参数与关键字参数混合使用(执行)
关键字参数可以和位置参数混合使用,但是传入的顺序是位置参数在前,关键字参数在后。

def func(a1, a2, a3):
    pass

func(1, 2, a3=3)
func(1, a2=2, a3=3)
func(a1=1, a2=2, a3=3)
'''
func(a1=1, 2, 3)  # 错误
func(a1=1, 2, a3=3)  # 错误
func(a1=1, a2=2, 3)  # 错误
'''

⑤ 默认参数(定义)
默认参数,可传可不传。如果传参,覆盖掉原来的值,否则使用默认值。

def func(a1, a2, a3=3, a4=4):
    pass
func(1, 2)
func(1, 2, 3)
func(1, 2, 3, 4)
func(1, 2, 3, a4=44)

⑥ 万能参数(参数打散)
不确定可以传入多少参数时可以使用。*args参数不支持关键字传参,只支持位置传参,可以接收任意个数的位置参数,并将参数转换成元组。

  • *args
# coding:utf-8
'''
不确定可以传入多少参数,接收任意数量的参数,*args不支持关键字传参,只支持位置传参
'''
def func(*args):  # 一般情况下写args:参数
    print(args)

func(1)  # args = (1,)
func(1, 2)  # args=(1, 2)
func(1, 2, 'thanlon', [1, 2])  # args =(1, 2, 'thanlon', [1, 2])
func((1, 2, 3))  # args =((1, 2, 3),)
func(*(1, 2, 3))  # args =(1, 2, 3)
'''
'''
def func2(a1, *args):  # 一般情况下写args:参数
    print(a1)

func2(a1=1)
# func2(a1=1,1)#违反位置参数在关键字参数后
def func2(*args, a1):  # 一般情况下写args:参数
    print(a1)

func2(1, 2, 3, a1=4)
def func(a1=1, *args, a2):  # 一般情况下写args:参数
    print(a1, args, a2)
    
func(11, 2, 3, a2=4)
'''
11 (2, 3) 4
'''
  • **kwargs
    可以接收任意个数的关键字参数,并将参数转换成字典。
# coding:utf-8
def fun(**kwargs):  # kwargs:键值参数
    print(kwargs)
    
fun(k1=1, k2='thanlon')  # kwargs = {'k1':1,'k2':'thanlon'}
fun(**{'k1': 'v1'})  # kwargs ={'k1': 'v1'}
  • args与*kwargs的综合使用
# coding:utf-8
def fun(*args, **kwargs):
    print(args, kwargs)

fun(1, 2, 3, k1=1, k2=2)  # (1, 2, 3) {'k1': 1, 'k2': 2}
# fun(k3=3, 1, 2, 3, k1=1, k2=2)  #错误
fun(*[1, 2, 3], 2, 3, k1=1, k2=2)  # (1, 2, 3, 2, 3) {'k1': 1, 'k2': 2}
# fun(**[1, 2, 3], 2, 3, k1=1, k2=2)  # 错误
fun(*[1, 2, 3], **{'k1': 1, 'k2': 2})  # (1, 2, 3) {'k1': 1, 'k2': 2}
fun(1, 2, 3 * [1, 2, 3], **{'k1': 1, 'k2': 2})  # (1, 2, [1, 2, 3, 1, 2, 3, 1, 2, 3]) {'k1': 1, 'k2': 2}
fun(1, 2, 3 * [1, 2, 3], k3=3,**{'k1': 1, 'k2': 2})  # (1, 2, [1, 2, 3, 1, 2, 3, 1, 2, 3]) {'k3': 3, 'k1': 1, 'k2': 2} ,特殊情况:违背位置参数在前面

⑦ 参数的重点(工作常用到的)
定义函数:

def func1(a,b):
    pass
def func2(a,b=None):
    pass
def func3(*args,**kwargs):
    pass

调用函数:位置参数在关键字参数之前

⑧ 面试题(概率高)
对于函数参数的默认值慎用可变类型,理解下面的例子,你就知道这个坑了……

# coding:utf-8
'''
问题1:def func(a,b=[])有什么陷阱?
如果第二个参数没有传入,在函数作用域会使用空列表,空列表会一直存在;如果传入,在列表作用域中会使用传入的列表。
问题2:看代码写结果?
'''
def func(a, b=[]):
    b.append(a)
    return b

lst01 = func(1)  # 此时b=[1]
lst02 = func(1, [1, 2, 3])  # 传递的参数是列表
lst03 = func(2)  # 此时b = [1,2]

print(lst01)
print(lst02)
print(lst03)
'''
[1, 2]
[1, 2, 3, 1]
[1, 2]
'''

为加深理解,再给一个例子:

def func(a, b=[]):
    b.append(a)
    print(b)

func(1)
func(1, [1, 2, 3])
func(2)
'''
[1]
[1, 2, 3, 1]
[1, 2]
'''
5. 函数的返回值

注意:无返回的函数实际返回None

5.1 无参数无返回值
# coding:utf-8
# 情况1:无参数、无返回值
def f1():
    pass
f1()
5.2 有参数无返回值:
# 情况2:有参数、无返回值
def f1(arg):
    pass
    
f1(123)
5.3 无参数有返回值:
# 情况3:无参数、有返回值
def f1():
    return 1
    
v1 = f1()
5.3 有参数有返回值:
# 情况4:有返回值有参数的
def f1(arg):
    return 1
    
v2 = f1(123)
5.4 特殊情况:返回元组
# coding:utf-8
'''
特殊:返回元组
'''
def func():
    return 1, 2, 3, 'thanlon'

v = func()
print(v)
'''
(1, 2, 3, 'thanlon')
'''
5.2 参数传递练习题

① 用户输入一段字符串,计算字符串中有多少个A字符?将这些A字符写入A.txt文件中

# coding:utf-8
'''
用户输入一段字符串,计算字符串中有多少个A字符?将这些A字符写入A.txt文件中
'''
def get_str_count(arg):
    count = 0
    for item in arg:
        if item == 'A':
            count += 1
    return count

def write_str(data):
    if data == False:  # 或者len(data)==0
        return False  # 函数执行过程中,一旦遇到return,则停止函数的执行
    with open('A.txt', 'w', encoding='utf-8') as f:
        f.write(data)
    return True

content = input('请输入一段字符串:')
counter = get_str_count(content)
data = 'A' * counter
status = write_str(data)
if status:
    print('写入成功!')
else:
    print('写入失败!')

① 写一个函数,计算列表中有多少个数字,并打印出列表中数字的个?

# coding:utf-8
'''
问题:写一个函数,计算列表中有多少个数字,并打印出列表中数字的个
'''
def count_list_num(args):
    count = 0
    for item in args:
        if type(item) == int:
            count += 1
    print('列表中有%d个数字' % count)

count_list_num([1, 2, 3, 'thanlon'])
'''
列表中有3个数字
'''

③ 写一个函数,将一个列表中偶数索引位置的数据构造成另外一个列表

# coding:utf-8
'''
写一个函数,将一个列表中偶数索引位置的数据构造成另外一个列表
方法1
'''
def get_data_list(arg):
    lst = []
    for i in range(len(arg)):
        if i % 2 == 0:
            lst.append(arg[i])
    return lst

data = get_data_list([1, 2, 3])
print(data)
'''
[1, 3]
'''
# coding:utf-8
'''
写一个函数,将一个列表中偶数索引位置的数据构造成另外一个列表
方法2
'''
def get_data_list(arg):
    v = arg[::2]
    return v

data = get_data_list([1, 2, 3])
print(data)
'''
[1, 3]
'''
7. 函数的作用域
7.1 作用域分类

作用域分为全局作用域和部分作用域,函数的作用域属于局部作用域。在python中,python文件是一个全局的作用域,函数是局部作用域。局部作用域可以用自己的数据,还可以用全局作用域中的。但是,全局作用只能用自己的数据。

7.2 全局作用域与局部作用域

① 全局变量以后必须大写
② 一个函数就是一个作用域(其它语言不是,如:java是以代码块)
③ 作用域中查找数据规则:优先在自己的作用域中找数据,自己没有就去“父级”,还没有就去“父级”的“父级”,直到全局作用域。

全局作用只能用自己的数据,不能使用局部作用域的数据:

# coding:utf-8
a = 1
def f():
    b = 2
print(b)  # NameError: name 'b' is not defined

局部作用域找数据优先在自己内部找,如没有到全局中找:

# coding:utf-8
x = 10

def f1():
    x = 1
    print(x)

f1()
'''
1
'''
# coding:utf-8
x = 1

def func():
    x = 2
    print(x)
    def func2():
        x = 3
        print(x)

    print(x)
    func2()
func()
'''
2
2
3
'''
# coding:utf-8
x = 1

def func():
    x = 2
    print(x)
    def func2():
        print(x)
    x = 3
    func2()
    x = 10
    print(x)

func()
'''
2
3
10
'''
# coding:utf-8
item = 4
for item in range(10):  # 这个item在全局也可以使用
    pass
print(item)  # 9
# coding:utf-8
item = 10

def func():
    item = 8
    for item in range(10):  # 这个item在全局也可以使用
        pass
    print(item)

func()
print(item)
'''
9
10
'''
# coding:utf-8
item = 10

def func():
    item = 8

    def inner():
        print(item)

    for item in range(10):  # 这个item在全局也可以使用
        pass
    inner()

func()
'''
9
'''

局部作用域既可以用自己的变量,也可以用全部作用域中的(自己没有的数据到全局作用域中找):

# coding:utf-8
a = 1
def f():
    print(c)
c = 2
f()

但是,当函数的局部作用域使用全局作用域中的数据,而全局作用域中的数据在调用函数的后面。这种情况局部作用域是不能使用全局作用域中的数据,如:

# coding:utf-8
a = 1
def f():
    print(c)
f()
c = 2

函数之间可以调用,但是一个函数调用的函数只能是全局中有的函数:

# coding:utf-8
def f1():
    def f3():
        pass

def f2():
    f1()
    f3()  # 不能调用f3函数

子作用域只能找到父级中的值,默认无法重新为父级的变量进行赋值:

# coding:utf-8
'''
在自己的作用域再创建一个这样的值
'''
name = 'thanlon'

def func():
    name = '奈何'  # 在自己的作用域再创建一个这样的值
    print(name)

func()
print(name)
'''
奈何
thanlon
'''

全局变量可以读,但是修改时,变量需要是可变类型:

# coding:utf-8
name = [1, 2, 3]

def func():
    name.append(4)#不是重新赋值,是修改可变类型变量的值
    print(name)

func()
print(name)
'''
[1, 2, 3, 4]
[1, 2, 3, 4]
'''

如果非要对全局的变量进行赋值,可使用global与nolocal关键字。

7.3 global与nolocal关键字

① global关键字:找到全局的变量, 方便修改变量

# coding:utf-8
name = 'thanlon'

def func():
    global name
    name = 'kiku'
    print(name)

func()
print(name)
'''
kiku
kiku
'''
# coding:utf-8
name = ['thanlon', 'kiku']

def func():
    global name
    name = [] # 想赋什么值赋什么值
    print(name)
    name = 'thanlon'

func()
print(name)
'''
[]
thanlon
'''
# coding:utf-8
'''
global关键字的应用
'''
name = 'thanlon'

def func():
    name = 'kiku'
    def inner():
        global name
        name = 'haha'
    inner()
    print(name)

func()
print(name)
'''
kiku
haha
'''
7.4 nolocal关键字

找到上一级的变量,方便进行修改。

# coding:utf-8
'''
nonlocal
'''
name = 'thanlon'

def func():
    name = 'kiku'
    def inner():
        nonlocal name  # 找到上一级(父级)变量name
        name = 'haha'
    inner()
    print(name)

func()
print(name)
'''
haha
thanlon
'''
7.4 函数作用域练习(面试题)

看代码写结果:

def func():
    for num in range(10):
        pass
    v4 = [lambda:num+10,lambda:num+100,lambda:num+100]
    result1 = v4[1]()
    result2 = v4[2]()
    print(result1,result2)
func()

【答案】:109 109(比较简单)

引申:

# coding:utf-8
def func():
    for num in range(10):
        pass
    v4 = [lambda: num + 10, lambda: num + 100, lambda: num + 100]
    result1 = v4[1]()
    num = 100
    result2 = v4[2]()
    print(result1, result2)

func()
'''
109 200
'''
8. 函数初级
8.1 函数名当作变量传递
# coding:utf-8
# 将函数名赋值给一个变量
def func():
    print('func')

func2 = func
func2()
'''
func
'''
# coding:utf-8
'''
函数可以当作列表中的元素
'''
def func():
    print('func')

func_list = [func, func, func]
func_list[0]()
func_list[1]()
func_list[2]()
'''
func
func
func
'''
# coding:utf-8
'''
函数放集合中
'''
def func():
    print('func')

func_set = {func, func, func}
for item in func_set:
    item()
'''
func
'''
# coding:utf-8
'''
函数放在字典中
'''
def func():
    print('func')

def bar():
    print('func')

func_dict = {'k1': func, 'k2': bar}
func_dict['k1']()
func_dict['k2']()

'''
func
func
'''
# coding:utf-8
'''
函数也可以当作字典的key,但一般是当作v
'''
def func():
    print('func')
func_dict = {func: 'func()'}
# coding:utf-8
def func():
    pass

func_list = [func, func, func]  # 函数的地址
func_list2 = [func(), func(), func()]  # 执行函数,列表中放函数的返回值
print(func_list)
print(func_list2)
'''
[, , ]
[None, None, None]
'''
# coding:utf-8
def func():
    pass

info = {
    'k1': func,
    'k2': func()
}
print(info)
'''
{'k1': , 'k2': None}
'''
8.2 函数名当作参数传递
# coding:utf-8
def func(arg):
    print(arg)
def show():
    pass
func(show)  # 将函数地址传入
func(show())  # 首先执行函数,然后把函数的返回值传入
'''

None
'''
# coding:utf-8
def func(arg):
    print(arg())

def show():
    print(666)

func(show)
'''
666
None
'''
# coding:utf-8
def func(arg):
    print(arg())

def show():
    print(666)

res = func(show)
print(res)
'''
666
None
None
'''
8.3 函数初级练习题(面试题)
# coding:utf-8
'''
根据用户选择编号执行对应的函数
'''
def func1():
    print('func1')

def func2():
    print('func1')

def func3():
    print('func1')

def func4():
    print('func1')

while True:
    choice = input('请输入要执行的函数名:')
    func_dict = {
        'func1': func1,
        'func2': func2,
        'func3': func3,
        'func4': func4
    }
    func_name = func_dict.get(choice)  # 找到返回value,找不到返回None
    if func_name:
        func_name()
    else:
        print('没有找到这个key!')
9. lambda表达式
9.1 lambda表达式结构

函数名 = lambda 参数:函数返回值

9.2 三元运算与lambda

① 三元运算:为了解决简单的if else的情况,如:

# coding:utf-8
if 1 == 1:
    a = 123
else:
    a = 456
    
a = 123 if 1 == 1 else 456

② lambda表达式:为了解决简单函数的情况,如:

# coding:utf-8
def func(a1, a2):
    return a1 + a2

func1 = lambda a1, a2: a1 + a2
print(func1)
print(func1(1, 2))
'''
 at 0x0000027F4BB5C7B8>
3
'''
9.3 lambda几种写法
# coding:utf-8
func = lambda: 100
print(func())
'''
100
'''
# coding:utf-8

func = lambda x1: x1 ** 2
print(func)
print(func(10))
'''
 at 0x0000026AAD7EC1E0>
100
'''
# coding:utf-8

func = lambda *args, **kwargs: len(args) + len(kwargs)
print(func)
print(func(10, 20, 'thanlon', {'k1': 'v1'}, {'k2': 'v2'}))
'''
 at 0x000001F1FF71C1E0>
5
'''
# coding:utf-8

DATA = 100
func = lambda a1: a1 + DATA
print(func(100))
'''
200
'''
# coding:utf-8
DATA = 10

def func():
    DATA = 100
    func2 = lambda a1: a1 + DATA
    v = func2(100)
    print(v)

func()
'''
200
'''
# coding:utf-8

func = lambda n1, n2: n1 if n1 > n2 else n2
v = func(12, 13)
print(v)
'''
13
'''
9.3 lambda练习题

练习一:

# coding:utf-8
USER_LIST = []

def func(x):
    v = USER_LIST.append(x)  # 返回None,一般列表不返回新值
    return v

res = func('thanlon')
print(res)
'''
None
'''

练习二:

# coding:utf-8
def func(x):
    v = x.strip()
    return v

res = func('thanlon ')
print(res)
'''
thanlon
'''

练习三:

# coding:utf-8
USER_LIST = []

func = lambda x: USER_LIST.append(x)

res = func('thanlon')
print(res)
print(USER_LIST)
'''
None
['thanlon']
'''

练习四:

# coding:utf-8
func = lambda x: x.split('l')
v = func('thanlon')
print(v)
'''
['than', 'on']
'''

练习五:

# coding:utf-8
func_list = [lambda x: x.strip(), lambda y: y + 199, lambda x, y: x + y]
v1 = func_list[0]('thanlon')
v2 = func_list[1](1)
v3 = func_list[2](1, 2)
print(v1, v2, v3)
'''
thanlon 200 3
'''
9.3 匿名函数(面试)

什么是匿名函数?
lamda表达式也称为匿名函数,v = [lambda x:x+100,lambda x:x+100,]
下面不是匿名函数:

def func():
    pass
10. 内置函数

以上都是自定义函数,这里详细谈内置函数。

10.1 数学相关的内置函数
  • abs():取绝对值
# coding:utf-8
'''
abs():取绝对值
'''
v = abs(-1)
print(v) # 1
  • float():转换成浮点型(小数)
# coding:utf-8
'''
float():转换成浮点型(小数)
'''
v = float(55)
print(v)  # 55.0
  • max()/min():找到最大值/最小值
# coding:utf-8
'''
max():找到最大值
min():找到最小值
'''
lst = [1, 2, 3]
print(max(lst))
print(min(lst))
'''
3
1
'''
  • sum():求和
# coding:utf-8
lst = [1, 2, 3]
print(sum(lst))
'''
6
'''
  • divmod():两数相除的商和余
# coding:utf-8
'''
求商和余数
'''
res = divmod(1001, 3)
print(res)  # (200, 0)
a, b = divmod(1001, 3)
print(a, b)  # 333 2
  • pow(a,b):求a的b次方
# coding:utf-8
print(pow(2, 3))
  • round(a,n):保留小数(四舍五入)
# coding:utf-8
print(round(1.205020, 2))  # 1.21

练习题:内置函数应用(分页)

# coding:utf-8
'''
每页显示10页数据,用户根据输入的页面找到对应的数据
'''
every_data_count= 10
user_list = []
for i in range(0,105):
    temp = {
        'email':'20190801%[email protected]'%i
    }
    user_list.append(temp)

sum_data = len(user_list)
max_page_num,a = divmod(sum_data,every_data_count)

if a>0:
    max_page_num +=1

page = int(input('您需要查看第几页:'))
if page>max_page_num or page<1:
    print('页码不合法,必须是1~%s'%max_page_num)
else:
    #第一页:[0,10]
    #第一页:[10,20]
    #第一页:[20,40]
    start = (page-1)*10
    end = page*10
    # print(user_list[start:end])
    for item in user_list[start:end]:
        print(item)
10.2 输入输出的内置函数
  • input()
  • print()
10.3 强制转换的内置函数
  • dict()
  • list()
  • tuple()
  • int()
  • str()
  • bool()
  • set()
10.4 进制转换的内置函数
  • bin:将十进制转换为二进制
# coding:utf-8
# 将十进制转换成二进制
v = 10
result = bin(v)
print(result) # 0b1010
  • oct:将十进制转换成八进制
# coding:utf-8
# 将十进制转换成八进制
v = 10
result = oct(v)
print(result)  # 0o12
  • hex:将十进制转换成十六进制
# coding:utf-8
# 将十进制转换成十六进制
v = 10
result = hex(v)
print(result)  # 0xa
  • int:将其它进制转换成十进制
'''
默认转换成10进制
'''
# coding:utf-8
v = '123456'
result = int(v)  # 默认转换成10进制
print(result)  # 123456
# coding:utf-8
# 将二进制转换为十进制
v = '0b1010'
result = int(v, 2)
print(result)  # 10
# coding:utf-8
# 将八进制转换为十进制
v = '0o12'
result = int(v, 8)
print(result)  # 10
# coding:utf-8
# 十六进制转换成十进制
v = '0xa'
result = int(v, 16)
print(result)  # 10
10.5 编码相关的内置函数

① 将十进制转换成unicode编码中的对应字符[chr(int)]
unicode包括ASCII码,chr函数在python3之后才是unicode,之前只能表示ASCII码。

# coding:utf-8
v = chr(99)
print(v)  # c

② 根据字符转换成unicode编码中对应的十进制[ord()]

# coding:utf-8
'''
ord:根据字符在unicode编码中找到其对应的十进制
'''
v = ord('中')
print(v)  # 20013
# coding:utf-8
'''
ord:根据字符在unicode编码中找到其对应的十进制
'''
v = '奈何'
for item in v:
    val = ord(item)
    print(val)  # 20013
'''
22856
20309
'''

③ 应用:随机验证码

import random:导入一个random模块

v = random.randint(start,end):得到一个随机数

# coding:utf-8
import random

def get_random_code(lenth=4):
    data_list = []
    for i in range(0, lenth):
        v = random.randint(65, 90)
        data_list.append(chr(v))
    # print(data_list)
    return ''.join(data_list)

print(get_random_code())
10.5 其它
  • len()
  • open()
  • range(0
  • id()
  • type()

⑥ 内置函数相关应用:ip地址转换(面试题)

  • 面试热身(非面试题)
    请将 ip = “192.168.0.1”中的每一个十进制数转换为二进制,并通过“,”(逗号)将二进制连接起来组成一个新的字符串(0b11000000,0b10101000,0b0,0b1)。
# coding:utf-8
'''
ip = '192.168.0.1'------>'0b11000000,0b10101000,0b0,0b1'
'''
ip = '192.168.0.1'
ip_list = ip.split('.')
result = []
for item in ip_list:
    result.append(bin(int(item)))
print(','.join(result))
'''
0b11000000,0b10101000,0b0,0b1
'''
  • 面试题
    请将 ip = “192.168.0.1”中的每一个十进制数转换位二进制,将得到的二进制(去掉中间的点)转换成十进制数。
# coding:utf-8
'''
ip = '192.168.0.1'------>'11000000101010000000000000000001'->3232235521
'''
ip = '192.168.0.1'
ip_list = ip.split('.')
result = []
result_bin = ''
for item in ip_list:
    item_bin = bin(int(item))[2:]
    # print(item_bin)
    '''
    11000000
    10101000
    0
    1
    '''
    if len(item_bin) < 8:
        item_bin = '0' * (8 - len(item_bin)) + item_bin
    # print(item_bin)
    '''
    11000000
    10101000
    00000000
    00000001
    '''
    result_bin += item_bin
print('0b' + result_bin)  # 0b11000000101010000000000000000001(其实不加0b也是可以的)
print(int(result_bin, base=2))
'''
3232235521
'''

上面使用的是字符串,下面使用列表,当然使用列表还是使用字符串在这里不是重点:

# coding:utf-8
'''
ip = '192.168.0.1'------>'0b11000000,0b10101000,0b0,0b1'
'''
ip = '192.168.0.1'
ip_list = ip.split('.')
result = []
result_bin = ''
for item in ip_list:
    item_bin = bin(int(item))[2:]
    # print(item_bin)
    '''
    11000000
    10101000
    0
    1
    '''
    if len(item_bin) < 8:
        item_bin = '0' * (8 - len(item_bin)) + item_bin
    # print(item_bin)
    '''
    11000000
    10101000
    00000000
    00000001
    '''
    result.append(item_bin)
print(result)  # ['11000000', '10101000', '00000000', '00000001']
result = '0b' + ''.join(result)
print(result)  # 0b11000000101010000000000000000001
print(int(result, base=2))
'''
3232235521
'''
11. 函数中级
11.1 函数可以做返回值
def func1():
    print(123)
def func2():
    return func1
v = func2()
v()
name = 'thnalon'
def func1():
    print(name)
def func2():
    return func1
v = func2()
v()  # thnalon
name = 'thnalon'

def func():
    def inner():
        print(123)
    return inner

v = func()
v()
'''
123
'''
name = 'thnalon'

def func():
    name = 'kiku'

    def inner():
        print(name)
    return inner

v = func()
v()
'''
kiku
'''
name = 'thnalon'

def func(name):
    def inner():
        print(name)
    return inner

v = func('kiku')
v()
'''
kiku
'''
11.2 闭包

闭包:为函数创建一块区域为其维护自己的数据,以后执行时方便调用。
闭包应用场景:装饰器/SQLALchemy源码
补充:只要函数名加(),就会在内存空间开辟一块内存。

name = 'haha'

def func(name):
    def inner():
        print(name)
    return inner

v = func('kiku')  # 开辟内存,内存中{name = kiku,inner}为函数创建一块区域(内部变量供自己使用),为它以后执行提供数据。
v2 = func('thanlon')  # 开辟内存,内存中{name = thanlon,inner}
v() # 函数执行后,函数中的数据在内存中被销毁
v2() # 函数执行后,函数中的数据在内存中被销毁
'''
kiku
thanlon
'''

关于闭包可以记下面的例子:

# coding:utf-8
'''
函数嵌套函数,并且第一层函数返回嵌套函数的函数名
'''
def func(name):
    def inner():
        print(name)
    return inner

print(func('th'))
'''
thanlon
'''

看下面一个例子,真正区分什么是闭包。封装了值,并且还要用,这样才是闭包。

# 不是闭包,封装了name值,但是在内层函数中没有使用
def func(name):
    def inner():
        return 123

    return inner
# 是闭包,封装了值,还需要在内层函数中使用
def func2(name):
    def inner():
        print(name)
        return 123

    return inner
11.3 内置高阶函数
  • 对函数进行赋值
  • 把函数当作返回值

注意:可以对函数进行赋值

11.4 函数练习题

自己没有函数,执行父类中的函数:

name = 'thanlon'

def base():
    print(name)

def func():
    name = 'kiku'
    base() # 自己没有base函数,执行父类中的base函数

func()
'''
thanlon
'''
name = 'thanlon'

def func():
    name = 'kiku'
    def base():
        print(name)
    base()  # 自己没有base函数,执行父类中的base函数

func()
'''
kiku
'''
11.5 函数面试题
# coding:utf-8
info = []

def func():
    print(item)

for item in range(10):
    info.append(func)
info[0]()
'''
9
'''

理解下面这个题,差不多就彻底明白了:

# coding:utf-8
info = []

def func(i):
    def inner():
        print(i)
    return inner

for item in range(10):
    info.append(func(item))
info[0]()
info[1]()
info[2]()
'''
0
1
2
'''
11.6 总结

def func(arg):
    def inner():
        return arg
    return inner

base_list = []
func_list = []
for i in range(10):
    base_list.append(base)
    func_list.append(func(i))
# print(base_list)
# print(func_list)
'''
base_list与func_list中分别保存什么?
base_list中存储的都是base函数
func_list中存储的都是inner函数,但是每个inner是在不同的地址创建的
'''
'''
如果循环打印什么?
'''
for data in base_list:
    v = data()
    print(v)  # 9 9 9 9...9
for data in func_list:
    v = data()
    print(v)  # 0 1 2 3 ... 9
  • 传参:位置参数在前,关键字参数在后、
  • 函数不被调用,内部代码永远不执行
  • 每次调用函数时,都会为此次调用开辟一块内存,内存中保存自己以后以后想要用的值
  • 函数是作用域,如果自己作用域中没有,则往上级作用域找
13. 函数高级
13.1 常用的内置函数(面试)

常见的内置函数:open、id、type、len、range

13.2 filter/map/reduce(面试)
  • filter
    对序列中的元素进行筛选,最终获取符合条件的序列
# coding:utf-8
v = [1, 2, 3, 'thanlon', 'kiku']

def func(x):
    return True
'''
如果函数返回True,将v中的元素添加到空列表中
'''
result = filter(func, v)
print(result)  # 
print(list(result))  # [1, 2, 3, 'thanlon', 'kiku']
# coding:utf-8
v = [1, 2, 3, 'thanlon', 'kiku']

def func(x):
    if type(x) == int:
        return True
    return False

'''
如果函数返回True,将v中的对应的元素添加到空列表中
'''
result = filter(func, v)
# print(result)  # 
print(list(result))  # [1, 2, 3]
'''
[1, 2, 3]
'''

使用lambda表达式简化:

# coding:utf-8
v = [1, 2, 3, 'thanlon', 'kiku']

def func(x):
    # if type(x) == int:
    #     return True
    # return False
    # return type(x) == int
    return True if type(x) == int else False
'''
如果函数返回True,将v中的对应的元素添加到空列表中
'''
# result = filter(func, v)
# result = filter(lambda x:type(x) == int, v)
result = filter(lambda x: True if type(x) == int else False, v)
print(list(result))
'''
[1, 2, 3]
'''
  • map
    循环每个元素(第二个参数),然后让每个元素执行函数(第一个参数),将每个函数执行的结果保存到新的列表中并返回。
# coding:utf-8
'''
每个元素增加100
'''
v = [1, 2, 3]
for i in range(0, len(v)):
    v[i] += 100
print(v)
'''
[101, 102, 103]
'''
# coding:utf-8
'''
每个元素增加100
map一执行会循环终端中每一个元素,会将返回值添加到空列表中[]。
'''
v = [1, 2, 3]

def func(args):
    print(args)
    return args + 100

# 第一个参数:必须是一个函数
# map第二个值:必须是可迭代类型(可迭代类型就是可以被for循环的,字符床、列表、字典、集合)

result = map(func, v)
# print(result)  # 
print(list(result))
'''
1
2
3
[101, 102, 103]
'''

使用lambda表达式简化:

# coding:utf-8
v = [1, 2, 3]

def func(args):
    return args + 100

# result = map(func, v)
result = map(lambda args: args + 100, v)
# print(result)  # 在python2中,是[101, 102, 103]
# print(result)  # 在python3中返回的是map对象,节省内存不展示,
# 如果想拿到result中的值,转换成列表
print(list(result))
'''
[101, 102, 103]
'''
  • reduce
    对序列内所有元素进行累计操作
# coding:utf-8
import functools
v = [1, 2, 3]
def func(x, y):  # 需要有两个参数
    print(x, y)

result = functools.reduce(func, v)
print(result)
'''
1 2
None 3
None
'''
# coding:utf-8
import functools

v = [1, 2, 3]

# 第一次函数参数是1和2
# 第二次函数参数是3和3
# 第一次函数返回什么,第二次函数中第一个参数就是什么
def func(x, y):  # 需要有两个参数
    return x + y

result = functools.reduce(func, v)
print(result)
'''
6
'''
# coding:utf-8
import functools
v = ['I', 'Love', 'Kiku']

def func(x, y):  # 需要有两个参数
    return x + ' ' + y

result = functools.reduce(func, v)
print(result)
'''
I Love Kiku
'''

使用lambda表达式简化:

# coding:utf-8
import functools

v = ['I', 'Love', 'Kiku']

result = functools.reduce(lambda x, y: x + ' ' + y, v)
print(result)
'''
I Love Kiku
'''
14. 递归
14.1 什么是递归

函数自己调用自己。函数的递归效率低,因为每次调用函数,都要新开辟一块内存,也就是说内存不断在消耗。递归可以用,但是不到非用不可就不用,尽量通过循环来做。

14.2 默认递归限制的最大次数(面试题)

In [1]: import sys

In [2]: dir(sys)

In [3]: sys.getrecursionlimit()->Out[3]: 1000

python中默认递归限制的最大次数是1000次。

14.3 递归例子
  • 例1
def func(i):
    print(i)
    func(i+1)
func(1)
  • 例2
# coding:utf-8
'''
使用递归产生斐波那契数列
'''
def func(a, b):
    print(b)
    func(b, a + b)

func(0, 1)
  • 例3
# coding:utf-8
def func(a):
    if a == 5:
        return 100
    result = func(a + 1) + 10
    return result

val = func(1)
print(val)  # 140=100+10*4
'''
140
'''

你可能感兴趣的:(python函数详解)