python函数的学习笔记

python函数

1.函数的基本概念

  • 不使用函数,代码缺点:冗余,可读性很差,维护性太差

  • 函数:把多行代码封装成一个整体,在使用时直接调用。

  • 在Python里,使用关键字def来声明一个函数

  • def 函数名(参数):

    ​ 函数要执行的操作

  • 函数名也是一个标识符,由数字、字母或下划线组成,不能以数字开头,严格区分大小写;不能使用关键字

  • 遵守命名规范,使用下划线连接;顾名思义

  • 函数定义好了以后并不会自动执行,需要主动调用

  • 定义函数时传递的参数叫做形参,形参的值是不确定的,只是用来占位的

  • 函数调用时传入的参数,才是真正参与运算的数据,我们称之为实参

def tell_story(place, person1, person2):  # place,person1,person2是形式参数
    print("从前有座山")
    print("山里有座%s" % place)
    print("%s里有个%s" % (place, person1))
    print("还有一个%s" % person2)
    print("%s在%s讲故事" % (person1, person2))
    print("故事的内容是:")

age = int(input('请输入孩子的年龄:\n'))
if 0 <= age <= 3:
    for i in range(5):
        tell_story('尼姑庵', '师太', '小尼姑')  # 调用函数时传的参数是实参
elif 3 < age <= 5:
    tell_story('道观', '老道', '童子')  # 会把实参一一对应的传递,交给形参处理
else:
    print("别用这个故事忽悠了,换个花样吧")

# 还可以通过定义变量名的形式给形参赋值
tell_story(person2='青年', person1='禅师', place='武当山') 

2. 函数的返回值

  • 函数的返回值就是函数执行的结果,并不是所有的函数都必须要有返回值;
def add(a, b):
    c = a + b  # 变量C在外部是不可见的,只能在函数内部使用
    return c  # return 表示一个函数的执行结果

# 获取到 add 函数的结果,然后再求结果的 4 次方
result = add(1,2)
print(result**4)

# 如果一个函数没有返回值,它的返回就是None

# print就是一个内置函数
x = print('hello')  # None

age = input('请输入您的年龄:')
print(age)

3. 函数的注释

def add(a:int, b:int):  # :int 只是一个建议

    """
    这个函数用来将两个数字相加
    :param a: 第一个数字
    :param b: 第二个数字
    :return: 两个数字相加的结果
    """
    return a + b


# help(add)  # 查看函数的详情
x = add(1, 2)
print(x)

y = add('hello', 'world')
print(y)

z = add('hello', 5)
print(z)

4. 函数调用函数

  • 在一个函数内部调用了另外一个函数
def test1():
    print("test1开始了")
    print("test1结束了")


def test2():
    print("test2开始了")
    test1()
    print("test2结束了")


# 定义函数求n~m之间所有整数之和
def sumInt(m, n):
    su = 0
    for i in range(m, n + 1):
        su += i
   
    return su


# 求一个n的阶乘
def factor(n):
    x = 1
    for i in range(1, n + 1):
        x *= i

    return x


def sumFac(m):
    sumf = 0
    for i in range(1, m + 1):
        sumf += factor(i)

    return sumf


# 计算m阶乘的和 m = 6 ==>  1!+2!+3!+4!+5!+6!
def sumFactor(m):
    sumf = 0
    for i in range(1, m + 1):
        x = 1
        for j in range(1, i + 1):
            x *= j
        sumf += x

    return sumf


# test2()
# s = sumInt(1, 10) 
# print(s)  # 55
# y = factor(5)
# print(y)  # 120
# sf = sumFactor(6)
# print(sf)  # 873
sf1 = sumFac(6)
print(sf1)  # 873

5. 全局变量和局部变量

  • 在函数外部定义的变量是全局变量,在整个py文件里都可以访问
  • 在函数内部定义的变量,它是局部变量,只能在函数内部使用
  • 如果局部变量的名和全局变量同名,会在函数内部又定义一个新的局部变量
  • 内置函数 globals()可以查看全局变量 locals() 可以查看局部变量
  • 在Python里,只有函数能够分割作用域
a = 100  # 这个变量是全局变量,在整个py文件里都可以访问
word = 'butiful'


def Test():
    x = 'hello'  # 在函数内部定义的变量,它是局部变量,只能在函数内部使用
    print('x = {}'.format(x))
    # print('函数内部 a = {}'.format(a))

    # 如果局部变量的名和全局变量同名,会在函数内部又定义一个新的局部变量
    a = 10  # 在函数内部又定义了一个新的局部变量
    print('函数内部 a = {}'.format(a))

    # 函数内部如果想要修改全部变量
    global word
    word = 'ok'

    print('locals = {}, globals = {}'.format(locals(), globals()))


Test()
print('函数外部 a = {}'.format(a))
print('函数外部 word = {}'.format(word))

if 3 > 2:
    m = 'test'  # 条件成立时,m是全局变量,条件不成立,m未定义
print(m)

6. 函数多个返回值

  • 函数返回多个结果,就是将多个数据打包成一个整体返回
  • 可以使用列表和字典,通常情况下选择使用元组
def tst(a, b):
    x = a // b
    y = a % b
    # 一般情况下,一个函数置灰执行一个return语句
    # 特殊情况(finally语句)下,一个函数可能会执行多个return语句
    # return x  # return语句表示一个函数的结束
    # return y
    # return [x, y]
    # return {'x': x, 'y': y}
    # return (x, y)
    return x, y  # 返回的本质是一个元组


result = tst(12, 5)
print(result)
print('商是 {},余数是 {}'.format(result[0], result[1]))

quotient, remainder = tst(16, 3)
print('商是 {},余数是 {}'.format(quotient, remainder))

7. 默认参数的使用

  • 默认参数也就是缺省参数:有些函数的参数值,如果你传递了参数,就是用传递的参数,如果没有传递参数,就使用默认的值
  • 缺省参数要放在后面
# def say_hello(city='北京', name, age):  # 缺省参数要放在后面
def say_hello(name, age, city='北京'):
    print('大家好,我是{},我今年{}岁了,我来自{}'.format(name, age, city))


say_hello('李明', 18, '哈尔滨')  # 直接传递的参数叫做位置参数
say_hello('刘星', 19)
say_hello(age=15, name='查理', city='南京')  # 使用变量赋值传递的参数叫关键字参数
# 可以直接传递单个参数,也可以使用变量赋值的形式传参
# 如果有位置参数和关键字参数,关键字参数一定要放在位置参数的后面
say_hello('姚晨', age=15, city='南京')  # 如果传递参数,就使用传递的实参
# say_hello(name='鲁滨逊', 21, city='成都')  # 不能这样写

# print函数里end就是一个缺省参数
print('hello', '你好', sep='--', end='')

8. 可变参数的使用

  • *args便是可变位置参数
  • **kwargs表示可变的关键字参数
# *args 表示可变位置参数
# **kwargs 表示可变的关键字参数
def add(a, b, *args, mul=1, **kwargs):  # 缺省参数要放在可变参数的后面
    # print('a = {}, b = {}'.format(a, b))
    # print('args = {}'.format(args))  # 多出来的可变参数会以元组的形式保存到args里
    print('kwargs = {}'.format(kwargs))  # 多出来的关键字参数会以字典的形式保存
    s = a + b
    for arg in args:
        s += arg

    print(s + mul)


add(1, 3)
add(9, 5, 4, 2, 0)
add(1, 3, 5, 7, mul=2, x=0, y=4)  # kwargs = {'x': 0, 'y': 4},18

9. 函数的注意事项

  • 函数的三要素:函数名、参数和返回值
  • 在有一些编程语言(java,c)里,允许函数重名,在Python里不允许函数的重名
  • 如果函数重名了,后一个函数会覆盖前一个函数
  • python里,函数名也可以理解成一个变量名
def test(a, b):
    print('hello, a = {}, b = {}'.format(a, b))


def test(a):
    print('good, a = {}'.format(a))


test(3, 4)

test = 5
test(3)  # test 不再是一个函数,而是一个int变量,不能调用

10. 递归函数的使用

  • 递归简单来说,就是函数内部自己调用自己
  • 递归最重要的就是找到出口(停止的条件)
def test():
    print('test')
    test()


count = 0
def tell_story():
    global count
    count += 1
    print("从前有座山")
    print("山里有座庙")
    print("庙里有个老和尚")
    print("还有一个小和尚")
    print("老和尚在小和尚讲故事")
    print("故事的内容是")
    if count < 5:  # 设定递归停止的条件,5次以后停止
        tell_story()


# 求 1 ~ n 的和
def get_sum(n):
    if n == 0:
        return 0
    return get_sum(n-1) + n


# 使用递归求 n!
def get_factor(n):
    if n == 0:
        return 1
    return get_factor(n-1) * n


# 使用递归求斐波那契数列的第 n 个数字  1,1,2,3,5,8,13,21,34,55,89,144,233……
def fibonacci(n):
    if n == 1 or n == 2:
        return 1
    return fibonacci(n -1) + fibonacci(n - 2)

# tell_story()
# print(get_sum(5))
# print(get_factor(6))  # 720
print(fibonacci(6))  # 8

11. 匿名函数

  • 除了使用def 关键字定义一个函数以外,还可以使用 lambda 表达式定义一个函数

  • lambda x, y: x * y

  • 调用匿名函数两种方式:

    1. 给它定义一个名字(很少这样使用)

    2. 把这个函数当做参数传给另一个函数使用

def add(a, b):
    return a + b


# x = add(4, 5)  # 函数名(实参) 作用是调用函数,获取到函数的执行结果,并赋值给变量x
# print(x)

# print("0x%X" % id(add))
# fn = add  # 相当于给函数add起了一个别名fn
# print("0x%X" % id(fn))
# print(fn(3, 4))

# lambda a, b: a * b  # 匿名函数


def calc(a, b, fn):
    c = fn(a, b)
    return c


# def addi(a, b):
#     return a + b


# def minus(a, b):
#     return a - b


# x1 = calc(1, 2, addi)  # a=1,b=2,fn=addi
# x2 = calc(10, 5, minus)  # a=10,b=5,fn=minus
# print(x1, x2)

x3 = calc(5, 11, lambda x, y: x + y)
x4 = calc(16, 4, lambda x, y: x - y)
x5 = calc(4, 5, lambda x, y: x * y)
x6 = calc(12, 4, lambda x, y: x / y)
print(x3, x4, x5, x6)

12. 列表的sort方法和内置函数sorted

# 列表有几个内置函数和内置类,用了匿名函数
nums = [4, 8, 2, 1, 7, 6]
# nums.sort()
# print(nums)
tup = (5, 9, 2, 1, 3, 8, 7, 4)
# sorted内置函数,不会改变原有的数据,而是生成一个新的结果
# x = sorted(nums)
# print(x)
x1 = sorted(tup)
# print(x1)  # [1, 2, 3, 4, 5, 7, 8, 9]

students = [
    {'name': 'zhangsan', 'age': 18, 'score': 98, 'height': 180},
    {'name': 'lisi', 'age': 21, 'score': 97, 'height': 185},
    {'name': 'jone', 'age': 22, 'score': 100, 'height': 175},
    {'name': 'tony', 'age': 23, 'score': 90, 'height': 176},
    {'name': 'henry', 'age': 20, 'score': 95, 'height': 172}
]


# 字典和字典之间不能使用比较运算 <
# student.sort()

def foo(ele):
    # print("ele = {}".format(ele))
    return ele['height']

# 需要传递参数 key 指定比较规则
# key 参数类型是函数

# 在sort内部实现的时候,调用了foo方法,并且传入了一个参数,参数就是列表里的元素
# students.sort(key=foo)

students.sort(key = lambda ele: ele['score'])
print(students)

13. filter内置类、map和reduce

from functools import reduce

# filter 对可迭代对象进行过滤,得到的是一个filter对象,python2的时候是内置函数,python3修改成了一个内置类
# filter 可以给定两个参数,第一个参数是函数,第二个参数是可迭代对象

ages = [12, 23, 25, 30, 18, 22, 23, 30]
x = filter(lambda ele: ele > 18, ages)
# print(x)
# for i in x:
#     print(i)

# adult = list(x)
# print(adult)

nums = [12, 23, 25, 30, 18, 22, 23, 30]
# m  = map(lambda ele: ele + 2, nums)
# print(list(m))  # 把可迭代对象里的元素都执行函数里的动作

# reduce 以前是一个函数
# 内置函数和内置类都在 builtins.py文件里
# print(reduce(lambda ele1, ele2: ele1 + ele2, nums))  # 183

def foo(x, y):  # x=12,y=23;x=35,y=25;x=60,y-30;
    return x + y


# print(reduce(foo, nums))  # 183

students = [
    {'name': 'zhangsan', 'age': 18, 'score': 98, 'height': 180},
    {'name': 'lisi', 'age': 21, 'score': 97, 'height': 185},
    {'name': 'jone', 'age': 22, 'score': 100, 'height': 175},
    {'name': 'tony', 'age': 23, 'score': 90, 'height': 176},
    {'name': 'henry', 'age': 20, 'score': 95, 'height': 172}
]


def bar(x, y):
    return x + y['age']  # x = 0, y ={'name': 'zhangsan', 'age': 18, 'score': 98, 'height': 180}

# result = reduce(bar, students, 0)  # 0 是初始值
# print(result)
r1 = reduce(lambda x, y:x + y['age'], students, 0)
print(r1)  # 104,18+21+22+23+20

14. 内置函数的总结

# 1、abs 求绝对值
print(abs(-10), abs(5))  # 10, 5

# 2、all 把所有元素转换成布尔值,如果全是True,则返回True,否则返回False
print(all(['hello', 'world', 'everything']))  # True
print(all(['hello', 'world', 0]))  # False

# 3、any 只要有一个元素转换成为布尔值是True,结果就是True
print(any(['hello', None, 0]))  # True

# 4、ascii 把字符转换成ASCII码
print(ascii('a'))  # 'a'

# 5、bin 将数字转换成为二级制
print(bin(1))  # 0b1

# 6、chr 将字符编码转换成为对应的字符
print(chr(97))  # 'a'

# 7、ord 将字符转换成对应的字符编码
print(ord('A'))  # 65

# 8、dir 列出对象所有的属性和方法
# print(dir(list))  # [...'append', 'clear', 'copy', 'count', 'extend', 'index'... ]

# 9、divmod 求除法的商和余数
print(divmod(12, 5))  # (2, 2)

# 10、exit 以指定的退出码退出程序
# exit(200)

# 11、globals 用来查看所有的全局变量
a =1
print(globals())

# 12、locals 用来查看所有的局部变量
def foo():
    b = 2
    return b
print(locals())

# 13、help 用来查看帮助文档的
# help(list)

# 14、print 打印内容
# 15、input 让用户输入内容
# x = input('请输入')
# print(x)

# 16、isinstance 用来判断一个对象是否是由一个类创建出来的
# 17、issubclass 用来判断一个类是否是另一个类的子类
# 18、len 获取长度
# 19、iter 获取到可迭代对象的迭代器
# 20、next for...in循环本质就是调用迭代器的next方法
# 21、max 求最大数
# 22、min 求最小数
# 23、open 用来打开一个文件
# 24、pow 幂运算
# 25、round 四舍五入,保留到指定小数位
print(round(3.1415926, 2))
# 26、sum 用来求和
# 27、repr 把一个对象变成一个字符串
person = {'name': 'zhangsan'}
print(repr(person))  # "{'name': 'zhangsan'}"

15. 高阶函数

  • 一个函数作为另一个函数的参数
  • 一个函数作为另一个函数的返回值
  • 函数内部再定义一个函数
def foo():
    print('我是foo,我被调用了')
    return 'foo'


def bar():
    print('我是bar,我被调用了')
    # return foo()
    return foo


x = bar()
print(x)

y = bar()()
print(y)  # 'foo'


def outer():
    m = 100
    def inner():
        n = 90
        print('我是inner函数')

    print('我是outer函数')
    return inner


outer()
outer()()  # 调用内部函数
def tst():
    print('我是test函数')
    return 'hello'


def demo():
    print('我是demo函数')
    return tst


def bar():
    print('我是bar函数')
    return tst()


x = tst()
print(x)  # 'hello'

y = demo()  # y是test函数
print(y)  # <function tst at 0x0000020C2BF47310>
z = y()
print(z)  # 'hello'

a = bar()  # a是字符串'hello'
print(a)  # 'hello'

16. 函数的嵌套

def outer(x):
    m = 100
    print('我是outer函数')

    def inner():  # inner函数是定义在outer函数内部的一个函数
        n = 90
        print('我是inner函数')

    if x > 10:
        inner()
    return 'hello'

# inner()  # 在外部不能调用内部函数
outer(8)  # 只调用outer函数
outer(12)  # 调用了outer函数和inner函数

17. 闭包

  • 如果在一个内部函数里,对在外部作用域(但不是全局作用域)的变量进行引用,那么内部函数就被认为是闭包
def outer():
    x = 10  # x是局部变量

    def inner():
        y = x + 1

    return inner
  • 内部函数修改外部函数的局部变量的值
def outer():
    x = 10  # x是局部变量

    def inner():
        # 在内部函数修改外部函数的局部变量的值
        nonlocal x  # 此时,这里的x 不再是新增的变量,而是外部的局部变量
        y = x + 1
        x = 20  # 不是修改外部的x 变量,而是在inner函数内部又创建了一个新的变量x
        print(y)

    return inner

out()()  # y的值为11

18. 函数的运用

  • 计算一段代码的运行时间
import time


# start = time.time() # time模块里的time方法,可以获取当前时间的时间戳
# # 时间戳是从1970-01-01 00:00:00 UTC 到现在的秒数
# # 从1970-01-01 00:00:00 ~ 2021-04-05 10:15 UTC  东八区 需要减8个小时
# print('start = {}'.format(start))
#
# x = 0
# for i in range(1, 1000000):
#     x += i
#
# print(x)
# end = time.time()
# print('end = {}'.format(end))
#
# print('代码的运行耗时 {} 秒'.format(end - start))


def calc_time(fn):
    start = time.time()
    fn()
    end = time.time()
    print('代码的运行耗时 {} 秒'.format(end - start))


def demo():
    x = 0
    for i in range(1, 1000000):
        x += i
    print(x)

def foo():
    print('hello')
    time.sleep(1)
    print('world')


calc_time(demo)
calc_time(foo)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值