博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Python基础 - 06函数

Posted on 2021-10-10 16:12  Kingdomer  阅读(317)  评论(0)    收藏  举报

Python基础 - 06函数

一、函数基础

1.1 函数的定义和调用

"""
格式:
def 函数名([参数,......]):
    代码
调用函数: 函数名()
"""
函数名只能包含字母、数字和下划线_,且不能以数字开头。
函数头:以def开头的那行。
函数体:函数头后面所有缩进的代码。
return通常放在函数末尾,return语句执行时,Python跳出函数并返回到调用这个函数的地方。
 
import math
def area(radius):
    """
    Returns the area of a circle with the given radius.
    For example:
        > area(5.5)
        95.033177771091246
    :param radius: 半径
    :return: 返回圆的周长
    """
    return math.pi * radius ** 2

print(area.__doc__)

  

函数并非必须包含return语句
如果函数没有包含return语句,Python将认为它以下述代码行结束: return None
特殊值None用于指出函数不返回值。例:函数常被用于执行返回值无关紧要的任务,如在屏幕上打印输出。
 
除了返回值外,函数以其他任何方式所做的修改都被称为副作用(side effect);打印到屏幕、写入文件和下载网页都属于副作用。
有一种名为函数式编程的编程风格,其特征是几乎消除了副作用。在函数式编程中,只能通过返回值来完成修改。
Python为函数式编程提供了强有力地支持,包含在函数中定义函数以及将函数作为值传递给其他函数。

 

1.2 调用函数: 函数名()

print(2 ** 3)  # 8, m ** n m的n次方
print(3 % 2)   # 1, 取模, 取余数

number = int(input('输入一个3位整数:'))
print('个位数是:', number % 10)
print('十位数是:', number // 10 % 10)
print('百位数是:', number // 100)

 

1.3 自定义函数  

# 生成验证码
def generate_code():
    str = 'qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM'
    code = ''
    for i in range(4):
        r = random.choice(str)
        code += r
    return code

print(generate_code)    # <function generate_code at 0x00000004A8E7A8B0>
print(generate_code())  # iRES

 

 

二、函数参数

无参数:
def 函数名():
    pass
有参数:
def 函数名(参数1,参数2,参数3,......):
    pass

2.1 参数就是在调用函数时起到向函数中传值作用。

# 生成验证码
def generate_code(number):
    str = 'qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM'
    code = ''
    for i in range(number):
        r = random.choice(str)
        code += r
    return code

print(generate_code)     # <function generate_code at 0x00000004A8E7A8B0>
print(generate_code(4))  # iRES
print(generate_code(6)) # vg5WnM

 

def get_sum(a, b):
    s = a + b
    print(s)

get_sum(2, 3)             # 5
get_sum('hello','world')  # helloworld
get_sum(2,'3')            # TypeError: unsupported operand type(s) for +: 'int' and 'str'
# 对传入的值进行类型判断
def get_sum(a, b):
    if type(a) == type(b):
        s = a + b
        print(s)
    else:
        print('类型不一致')
# 判断是否是整型        
def get_sum(a, b):
    if isinstance(a, int)  and isinstance(b, int):
        s = a+b
        print(s)
    else:
        print('类型错误')   

2.2 默认值参数

def greet(name, greeting='hello'):
    print(greeting, name + '!')


greet('Bob')                  # hello Bob!
greet('Bob', 'Good morning')  # Good morning Bob!

在定义函数时,普通参数要位于默认值参数的前面。

def borrow_book(username, bookname, number=1, school='二中'):
    print('进入借书系统......')
    print('{} 要借阅的书名是{},借阅的数量:{}'.format(username, bookname, number))

borrow_book('张三', '西游记')
borrow_book('关羽', '三国演义', 10)
borrow_book('曹操','三国杀','一中')           # 曹操 要借阅的书名是三国杀,借阅的数量:一中
# 当有多个默认值参数时,传值指定参数名
borrow_book('曹操','三国杀',school='一中')    # 曹操 要借阅的书名是三国杀,借阅的数量:1
borrow_book(bookname='张三疯大闹龙宫', username='孙武')

缺省参数在*args后面

def sum_nums_3(a, *args, b=22, c=33, **kwargs):
    print(a)
    print(b)
    print(c)
    print(args)
    print(kwargs)

sum_nums_3(100, 200, 300, 400, b=1, c=2, mm=90, nn=91)
'''
100
1
2
(200, 300, 400)
{'mm': 90, 'nn': 91}
'''

 

list = [34,232,43,54,23,55,22]
def get_list(list):
    new_list = [e for e in list if e >= 50]
    print(new_list)

get_list(list)  #[232, 54, 55]

  

list = [34,232,43,54,23,5,55,22]
def remove_from_list(src_list):
    for e in src_list:
        if e < 50:
            src_list.remove(e)
    print(src_list)
# 当有多于两个小于50的值连续时,删除报错
remove_from_list(list)  # [232, 54, 5, 55] 

list = [34,12,232,222,43,54,23,5,55,22]
def remove_from_list2(src_list):
    n = 0
    while n < len(src_list):
        if src_list[n] < 50:
            src_list.remove(src_list[n])
        else:
            n += 1
    print(src_list)

remove_from_list2(list)

 

2.3 可变参数

 *args     -->  (), args参数是一个元祖

 **kwargs  -->  {}, kwargs参数是一个字典

def get_sum(*args):
    print(args)


get_sum(1, 2)                # (1, 2)
get_sum(1, 2, 3, 4)          # (1, 2, 3, 4)

a, *b, c = 1, 2, 3, 4, 5
print(a)                     # 1
print(b)                     # [2, 3, 4]
print(c)                     # 5

*a, b, c = 1, 2, 3, 4, 5
print(a)                     # [1,2,3]
print(b)                     # 4
print(c)                     # 5

ran_list = [23,45,6,7,88,99,22]
get_sum(*ran_list)           # (23, 45, 6, 7, 88, 99, 22)

 

def get_sum(*args):
    s = 0
    for i in args:
        s += i
    print('和:', s)

get_sum(1, 2)
get_sum(1, 2, 3, 4, 5, 6, 7)
list1 = [4, 5, 6, 7]
get_sum(*list1)
tup1 = (4, 5, 6, 7,)
get_sum(*tup1)

  

2.4 拆包和装包

函数装包:

def 函数(*args):  --> 此时出现装包操作
   pass

函数(1,2,3,4)

函数拆包:

list, tuple, set

调用的时候

函数(*list)  函数(*tuple)  函数(*set)

 

def show_book(**kwarge):
    print(kwarge)

show_book()               # {}

# TypeError: show_book() takes 0 positional arguments but 2 were given # show_book('红楼梦','西游记')
show_book(bookname='红楼梦', author='曹雪芹') # {'bookname': '红楼梦', 'author': '曹雪芹'} show_book(bookname='西游记') show_book(bookname='红楼梦', author='曹雪芹',page=1000)
book = {'bookname': '三国演义', 'author': '罗贯中'} show_book(**book) # {'bookname': '三国演义', 'author': '罗贯中'}

  

# 可变参数
def show_book2(*args, **kwargs):
    print('args -->: ', args)
    print('kwargs---->: ', kwargs)

book = {'bookName': '三国演义', 'author': '罗贯中', 'number': 5}
show_book2('枪枪', '三毛')
# args -->:  ('枪枪', '三毛')
# kwargs---->:  {}

show_book2('枪枪', '三毛', **book)
# args -->:  ('枪枪', '三毛')
# kwargs---->:  {'bookName': '三国演义', 'author': '罗贯中', 'number': 5}

print(book, 'hello', sep='--')              # {'bookName': '三国演义', 'author': '罗贯中', 'number': 5}--hello
print('{}{}{}'.format('AA','BB','CC'))                         # AABBCC
print('{name}-{age}-{sex}'.format(name='张顺',age=18,sex='男')) # 张顺-18-男
print('{name}-{age}-{sex}'.format(age=28,name='三顺',sex='女')) # 三顺-28-女
#print('{name}-{age}-{sex}'.format(38,'二顺','女'))             # KeyError: 'name'

print("-".join(["a",'b'])) # a-b
list2=['1','2','aa','90']  # 必须是字符串
print("-".join(list2))     # 1-2-aa-90

 

三、返回值: 将函数内的内容向外界传递

当函数调用时通过return向外返值。只要函数有返回值,需要接收。

return 后面的值可以是一个值,也可以是多个值。如果是多个值,return a, b, c, 会将多个值封装到一个元祖中。

def get_sum(*args):
    total = 0
    for i in args:
        total += i
    return total


t = get_sum(1, 2, 3)
print(t)

 

def get_maxandmin(numbers):
    for i in range(0, len(numbers) - 1):
        for j in range(0, len(numbers) - 1 - i):
            if numbers[j] > numbers[j + 1]:
                numbers[j], numbers[j + 1] = numbers[j + 1], numbers[j]

    min = numbers[0]
    max = numbers[-1]
    return min, max


list1 = [34, 11, 46, 78, 100, 36, 79, 88, 91]
result = get_maxandmin(list1)
print(result)                  # (11, 100)
a, b = get_maxandmin(list1)
print(a, b)                    # 11 100

  

def create_nums(num):
    print('------1----------')
    if num == 100:
        print('------2----------')
        return num +1
    else:
        print('------3----------')
        return num +2
    print('------4----------')
result1 = create_nums(100)
print(result1)
result2 = create_nums(200)
print(result2)

# ------1----------
# ------2----------
# 101
# ------1----------
# ------3----------
# 202

  

def abc():
    print('---------')
    for i in range(5):
        if i == 3:
            # break
            return
        print('i-->',i)
    print('=========')
abc()
#  break 时
---------
i--> 0
i--> 1
i--> 2
=========

# return 时
---------
i--> 0
i--> 1
i--> 2

 

四、 函数文档注释

def login(username, password):
    """
    用户登录
    :param username:  用户名
    :param password:  密码
    :return: 是否登录成功
    """
    if username == 'admin' & password == '123':
        return True
    else:
        return False
login()

 

 

查看函数的注释  

print(help(login))

Help on function login in module __main__:

login(username, password)
    用户登录
    :param username:  用户名
    :param password:  密码
    :return: 是否登录成功

  

五、函数特性

5.1 可变与不可变

不可变类型: 当改变变量的值时,地址发生了变化。      类型: int、 str、 float、 bool、 tuple
可变类型: 里面的内容发生了变化,地址没有发生改变。   类型: list、 dict、 set
 
a = 100
print(id(a))        # 211165337040
a = 90
print(id(a))        # 211165336720

tup1 = (1, 2, 3)
print(id(tup1))     # 484893742080
tup1 = (1, 2, 3, 4)
print(id(tup1))     # 484893778384
list1 = [1, 2, 3]
print(id(list1))    # 185050045568
list1.append(4)
print(id(list1))    # 185050045568

  

library = ['红楼梦', '西游记', '水浒传']

def add_book(bookname):
    if bookname not in library:
        library.append(bookname)
        print('添加图书<<{}>>成功'.format(bookname))
    else:
        print('已经存在此书')

def show_book():
    print('图书馆的书籍如下:')
    for book in library:
        print(book)

show_book()
add_book('张三的家')
show_book()

 

5.2 全局变量和局部变量

声明在函数外面的变量称为全局变量,声明在函数内部的变量称为局部变量。
函数内部可以直接使用全局变量,但是不能直接修改全局变量。如果想要修改全局变量,必须使用关键字:global 变量名
 
global 关键字的添加:  只有不可变的类型才需要添加global;可变的类型不需要添加global
在函数中出现global 全局变量的名字,那么函数中即便出现和全局变量名称相同的变量,也理解为对全局变量进行修改,而不是定义局部变量

 

def test1():
    a = 0
    print('a =', a)
test1()                    # a = 0
# ------------------------
a = 100
def test1():
    a = 0
    print('a =', a)
test1()                    # a = 0
# -----------------------
a = 100
def test3():
    a = 0
    b = 8
    print('a =', a)
    print('b =', b)
test3()                   # a = 0   b = 8
#------------------------
def test4():
    b = 9
    print('a =', a)
    print('b =', b)

test4()                   # a = 100     b = 9

 

a = 100
def test5():
    a -= 10 
    print('a =', a)

#test5()                  # UnboundLocalError: local variable 'a' referenced before assignment
# ---------------------- 使用global 声明变量为全局变量
a = 100
def test6():
    global a
    a = 99
    print('a =',a)
test6()                   # a = 99
print(a)                  # 99
# ---------------------- 对全局变量的多次修改
a = 100
def test5():
    global a
    a -= 10
    print('a =', a)
def test6():
    global a
    a = 99
    print('a =',a)
test6() # a = 99 print(a) # 99 test5() # a = 89

 

查看全局变量使用: globals() 字典:分成 系统 和自定义

print(globals())
# {'__name__': '__main__', '__doc__': None, '__package__': None,
# '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000086344C2FD0>,
# '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>,
# '__file__': 'E:\\PythonLearn\\pythonBase\\01door\\test.py',
# '__cached__': None, 'a': 10, 'abc': <function abc at 0x00000086344290D0>}

 

5.3 函数间调用

def aa(flag):
    if flag:
        print('aaaaa')
    else:
        print('bbbbb')
    b()

def b():
    print('BBBBB')

aa(1)  # aaaaa \n BBBBB

 

5.4 引用

在Python中,值是通过引用来传递的。

可以用id()来判断两个变量是否为同一个值的引用。可以将id值理解为内存的地址标识。

aaa = 10
b = aaa
c = aaa
print(id(aaa))
print(id(b))
print(id(c))

import sys

print(sys.getrefcount(aaa))  # 25
print(sys.getrefcount(b))    # 25

list1 = [1, 2, 3, 4, 5]
list2 = list1
list3 = list1
print(sys.getrefcount(list1))  # 4
del list3
print(sys.getrefcount(list1))  # 3

a = 1
b = a
print(b)    # 1
a = 2
print(a)    # 2
print(b)    # 1

a = [1, 2]
b = a
print(b)  # [1, 2]
a.append(3)
print(a)  # [1, 2, 3]
print(b)  # [1, 2, 3]

  

5.5 引用当做实参

可变类型和不可变类型的变量,作为函数参数时, 

def test1(n1):
    for i in range(n1):
        print('---->', i)
    n1 += 1

n = 9
test1(n)  # 赋值后n 和 n1 都指向9, n1 + 1 后n1 指向10, n 还是指向9
print(n)  # 9

list1 = [1,2,3]
def test2(l):
    if isinstance(l,list):
        for i in l:
            print('+++>', i)
        l.insert(0,8)
    else:
        print('不是列表')

test2(list1)  # list1 和 l 都指向[1,2,3]这块地址, 在函数内部操作完后,l 被删除。
print(list1)  # [8, 1, 2, 3]