python基础之函数重点

房东的猫 提交于 2019-11-27 03:41:55

函数的返回值

现在有一个需求,比较两个人的月薪,然后想获取月薪较大人的年薪。
如果需要在程序中拿到函数的处理结果做进一步的处理,则需要函数必须要有返回值。
需要注意的是:

  • return是一个函数结束的标志,函数内可以有多个return,只要执行到return,函数就会执行。
  • return的返回值可以返回任意数据类型
  • return的返回值无个数限制,即可以使用逗号隔开返回多个值
    • 0个:返回None
    • 1个:返回值是该值本身
    • 多个:返回值是元组
#返回单个值
def max_self(salary_x, salary_y):
    if salary_x > salary_y:
        return salary_x
    else:
        return salary_y
max_salary = max_self(20000, 30000)
print(max_salary*12)

##360000


#返回多个值
def fun():
    name = 'nick'
    age = 19
    hobby_list = ['read', 'run']
    return name, age, hobby_list
    
name, age, hobby_list = func()#解压缩
print(f"name,age,hobby_list: {name, age, hobby_list}")

##name,age,hobby_list:{'nick', 19, ['read', 'run']}

函数的调用

#函数调用的三种方式

def max_self(x, y):
    if x>y:
        return x
    else:
        return y
 # 1.
 max_self(1, 2)
 # 2.
 res = max_self(1, 2)*12
 # 3.
 max_self(max_self(20000, 30000),40000)

函数的参数

#形参,本质是变量名
def func(x, y):
    print(x)
    print(y)
    
##位置形参
def func(x, y):
    print(x)
    print(y)

##默认形参
def fun(x, y=10):
    print(x)
    print(y)
func(2)

'''
注意:
    1.位置形参必须放在默认形参的左边
    2.默认形参的值只在定义阶段赋值一次,也就是说默认参数的值在函数定义阶段就已经固定了
'''


#实参,本质是变量的值
func(1, 2)

#位置实参,函数调用阶段,按照从左到右的顺序依次定义的实参。
func(1, 2)

#关键值实参,调用函数时,按照key=value的形式指定的参数传值
func(y=2, x=1)

'''
注意:
    1.可以混用位置实参和关键字实参,但是位置实参必须在关键字实参的左边
    2.可以混用位置实参和关键字实参,但不能对同一个形参重复赋值
    
func(x, y=2)
func(y=2, x) # SyntaxError:positional argument follows keyword argument
func(x, x=1) # NameError: name 'x' is not defined
'''

'''

可变长参数

#可变长参数之*
## 形参(会把溢出的位置实参全部接收,然后存成元组形式,然后把元组赋值给*后的参数)
def sun_self(*args):
    res = 0
    for num in args:
        res += args:
    return res

res = sun_self(1, 2, 3, 4)
print(res)
### 10

## 实参(会把*后参数的值循环取出,打散成位置实参,遇到了就想到去打散)
def func(x, y, z, *args):
    print(x, y, z, args)
    
func(1, *(1, 2), 3, 4):
### 1 1 2 (3, 4)



#可变长参数之**
## 形参(**会把溢出的关键字实参全部接收,存储成字典的形似,然后把字典赋值给*后的参数)

def func(**kwargs):
    print(kwargs)
  
func(a=5)

### {'a', 5}

## 实参(**会将**后的参数的值循环取出,打散成关键字实参,遇到了就想到去打散)
def func(x, y, z, **kwargs):
    print(x, y, z, kwargs)
    
func(1, 3, 4, **{'a': 1, 'b': 2})

### 1 3 4 {'a': 1, 'b': 2}

函数对象

'''
函数是第一类对象,即函数可以被当作数据处理
'''
def func():
    print('from func')
print(func)

###<function func at 0x10af72f28>

#函数对象的四大功能
##1.引用
x = 'hello nick'
y = x

f = func
print(f)

###<function func at 0x10af72f28>

##2.当做参数传给一个函数
len(x)

def foo(m):
    m()
    
foo(func)

### from func

##3.可以当做函数的返回值
def foo(x):
    return x

res = foo(func)
print(res)
res()

###<function func at 0x10af72f28>
###from func


##4.可以当做容器类的元素
i = [x]

function_list = [func]
function_list[0]()

###from func

名称空间和作用域

"""
1.内置名称空间
    存放Python解释器自带的名字,如int、float、len
    在解释器启动时生效,在解释器关闭时失效
""" 
'''
2.局部名称空间
    用于存放函数调用期间函数体产生的名字,如f2
    在文件执行时函数调用期间时生效,在函数执行结束后失效
'''

def f1():
    def f2():
        print('from f2')
    f2()
    
f1()

'''
2.全局名称空间
    除了内置和局部的名字之外,其余都存放在全局名称空间,如x, func, 1, z
'''
x = 1

def func():
    pass

l = [1, 2]

if 3 > 2:
    if 4 > 3:
        z = 3       

#加载顺序

##内置---》全局---》局部

#查找顺序

##当前位置--->局部---》全局---》内置
        
        
x = 1
def func():
    print(x)
x = 10
func()

#10


##作用域
###全局作用域

x = 1

def bar():
    print(x)

bar() #1

###局部作用域
def f1():
    def f2():
        def f3():
            print(x)
        x = 2
        f3()
    f2()
 
f1() #2

'''
作用域注意点

x = 1

def f1(): #定义阶段 x = 1
    print(x)
    
def f2():
    x = 2
    f1()
    
f2() #1

'''

#作用域的应用
def f1():
    def inner():
        print('from inner')
    return inner
    
f = f1() #把局部定义的函数放在全局之中

def bar():
    f()
    
bar()

# from inner

## global关键字
x = 1

def f1():
    x = 2
    
    def f2():
        #  global x  # 修改全局
        x = 3
    f2()
    
f1()
print(x) # 1

x = 1
def f1():
    x = 2
    
    def f2():
        global x
        x = 3
    f2()
    
f1()
print(x)n # 3(global把x声明为全局变量之后,x指向3这个变量值,所以打印的是3)

##nonlocal

x = 1

def f1():
    x = 2
    
    def f2():
        x = 3
    f2()
    print(x)
    
f1() # 2

x = 1

def f1():
    x = 2 
    def f2():
        nolocal x  #针对嵌套函数局部之间的修改
        x = 3
    f2()
    print(x)
    
f1() # 3


'''
注意点:
    1.在局部想要修改全局的可变类型,不需要任何声明,可以直接修改。
    2.在局部如果想要修改全局的不可变类型,需要借助global声明,声明为全局的变量,即可直接修改
    
'''

lis = []

def f1():
    lis.append(1)
    
print(f"调用函数前:{lis}")
f1()
print(f"调用函数后:{lis}")

'''
调用函数前:[]
调用函数后:[1]
'''

闭包函数和装饰器

#闭包函数

def outter(x):
    x = 1
    
    def inner():
        print(x)
    return inner

f = outter(1)
f()
f()
f()

# 1
# 1
# 1

#闭包函数的应用
import requests

def outter(url):
    def get():
        response = requests.get(url)
        print(response.text)
    return get
    
baidu_spider = outter('https://www.baidu.com')
baidu_spider() #直接爬取百度网页


#装饰器


# 直接在模板里面加入登录功能
def deco(func):
    def wrapper(*args, **kwargs):
        #登录功能
        inp_username = input('请输入用户名:')
        inp_password = input("请输入密码:")
        if inp_username == 'nick' and inp_password == '123':
            print("登录成功")
        else:
            print("登录失败")
        res = func(*args, **kwargs)
        return res
    return wrapper
@deco

def shopping():
    print("欢迎来到购物模块")

shopping()

'''
#装饰器模板

def deco(func):
    def wrapper(*args, **kwargs):
        res = func(*args, **kwargs)
        return res
    return wrapper
'''

迭代器

#可迭代的对象:Python内置str、list、tuple、dict、set、file都是可迭代对象。

'''
特点:
    1.内置有__iter__方法的都叫可迭代的对象
'''


'''
迭代器对象:执行可迭代对象的__iter__方法,拿到的返回值就是迭代器对象。

特点:
内置__next__方法,执行该方法会拿到迭代器对象中的一个值
内置有__iter__方法,执行该方法会拿到迭代器本身
文件本身就是迭代器对象。

缺点:
取值麻烦,只能一个一个取,并且只能往后取,值取了就没了
无法使用len()方法获取长度
'''


#for循环:称为迭代器循环,in后必须是可迭代对象

'''
因为迭代器使用__iter__后还是迭代器本身,因此for循环不用考虑in后的对象是可迭代对象还是迭代器对象。

由于对可迭代对象使用__iter__方法后变成一个迭代器对象,这个迭代器对象只是占用了一小块内存空间,他只有使用__next__后才会吐出一个一个值。如lis = [1,2,3,4,5,...]相当于一个一个鸡蛋,而lis = [1,2,3,4,5,...].__iter__相当于一只老母鸡,如果你需要蛋,只需要__next__即可
'''
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!