A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

[学习交流] Python函数

© 专注的一批 中级黑马   /  2020-9-15 11:37  /  3170 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

函数
==

作用:最大化代码重用,最小化代码冗余,过程分解(方便维护)

一、函数的定义
-------

*   函数定义后不会被执行,只有被调用的函数才会被执行
   
*   函数名称只能是由字母、数字、下划线组成,其不能以数字开头
   

```python
`# 格式:
def 函数名(形参,....):  # 可不设置形式参数
    函数体
   
# 例1:加法函数
def add(a,b):
    c = a+b
    print("加法结果:",c)   # 拓展:print(add) 输出结果为方法 add函数的储存空间位置
   
# 例2:减法函数
def sub(a,b):
    c = a-b
    print("减法结果:",c)`

```

二、函数的调用
-------

```python
`# 格式:
函数名(输入实际参数值....)

# 例:调用加法函数
add(2,1)`


```

三、函数的返回(return)
---------------

```python
`# 格式:
def 函数名():
    函数体
    return  "返回值"

# 例:
def  add(a,b):
    c = a+b
    print(c)
    return   c   # 返回值,哪个调用就给哪个返回c

sum = add(1,2)   # 调用函数
print("sum = " , sum)`

亨达代理申请https://www.kaifx.cn/broker/hantecmarkets.html


```

*   注意:
    *   当函数执行到return的时候,就会马上终止函数执行
        
    *   函数中可以出现多个return,但有且只有一个return会被执行
        
    *   return 后面可以不跟值,return 单独使用等价于return None
        

四、变量作用域
-------

*   作用域范围:Built_in > Global > Enclousure > Local
   
*   作用范围采用就近原则
   

### 1.python内置函数变量Built_in:

```python
`def len():
    print("我自己定义的方法")
   
len("abcdef")  # 输出结果报错,并不是执行python的内置函数len()计算长度

# 自己定义的len()函数覆盖python的内置函数len()`


```

### 2.全局变量Global:

*   在函数外部定义的变量,全局指的是该变量在当前python文件范围内是可见的,全局变量可以被当前python文件内所有函数直接使用。
*   局部变量的优先级大于全局变量(变量就近原则)

```python
`# 例:
a = 10             # 全局变量,全局变量作用域是所有地方
c = 20
def test1():
    a=20           # 函数局部变量只能在自己的函数内使用
    print(a)

test1()       # 输出结果 : 20
print(a)      # 输出结果 : 10`



```



### 3.封装变量Enclousure:

```python
`def func1():
    x=100
    def nested1():
        x=99
        print(x)
    nested1()
    print(x)
        
func1()
#输出结果:
# 99
# 100

# 修改封装变量:nonlocal
def func2():
    x=100
    def nested2():
        nonlocal x
        x=99
        print(x)
    nested2()
    print(x)
      
func()

#输出结果:
# 99
# 99`


```

### 4.局部变量Local:

*   在函数内部定义的变量,该变量只能在定义的函数内部使用
   
*   全局变量能够同时作用于函数内外,如果想要在函数内部给一个定义在函数外的变量赋值,那么这个变量就不能是局部的,其作用域必须为全局的,可以通过global来定义。
   
*   函数内定义全局变量: global 命令
   

```python
`a=1
def test1():
    global  a       # 定义函数内的全局变量,
    a=10           # 函数内全局变量定义格式:先定义,再赋值,不可写成一行,否则报错
    print(a)
   
#调用函数后,全局变量才能起作用
print(a)
test1()                                    
print("在函数外调用test1函数的全局变量:",a)   # 输出结果:在函数外调用test1函数的全局变量:10

#输出结果:
#1在这里插入代码片
#10
#10`




```

*   一个变量已在函数外定义,如果在函数内需要为这个变量赋值,并要将这个赋值结果反映到函数外,可以在函数内用global声明这个变量,将其定义为全局变量。
   
*   在函数内部直接将一个变量声明为全局变量,在函数外没有声明,在调用这个函数之后,将增加为新的全局变量。
   

五、参数
----

```python
`def func(a,b,c):  # 形参a、b、c
        print(a,b,c)

func(1,2,3)       # 实参1、2、3`



```

### 1. 必备参数(位置匹配)

*   必备参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样
   
    ```python
    `def sub(a,b):
        c = a-b
        print("减法结果:",c)
   
    sub(1,2)    # 按形参顺序传值   a=1  b=2 输出结果:-1`
   
   
   
   
    ```
   

### 2. 关键字参数

*   关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
   
*   使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值
   
    ```python
    `def sub(a,b):
        c =a-b
        print(c)
   
    sub(b=2,a=1)    # 输出结果:-1
    #b=2,a=1  关键字参数
    #关键字传值与顺序无关`
   
   
   
   
    ```
   
*   注意:**调用函数时既传递位置参数又传递关键字参数时,位置参数要在关键字参数前面如: add(200,300,400,num5=100)**
   

### 3. 默认参数(调用时省略传值)

*   调用函数时,默认参数的值如果没有传入,则被认为是默认值
   
*   格式:
   
    ```python
    `def 函数名(... , ... , 形参名=默认值):
        函数体`
   
  
   
    ```
   
*   注意:**默认值参数必须出现在函数参数列表最右端,且任何一个默认参数右边不能有非默认参数**
   
*   例:
   
    ```python
    `def func2(a,b=2,c=3):
        print(a,b,c)
   
    func(1)      #输出结果:1 2 3
    func(1,2)    #输出结果:1 2 3
    func(1,c=5)  #输出结果:1 2 5`
   
   
    ```
   

默认值参数必须出现在函数参数列表的最右端,如果某一个位置的形参设置了默认参数,那么该位置之后的所有参数都必须设置为默认参数

### 4. 不定长参数(定义函数时,定义可接收多实参数据的形参)

需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数

定义一个可以接收任意数量参数的函数时需使用不定长参数: `*args`与 `**kwargs`

#### 4.1 `*args`

*   `*args`用来接收多个实参并将其放在一个**元组**中;
   
*   `*args`表示多参数传值,*号为关键格式,后面名称可随意改
   
    ```python
    `# 例1:
    # 定义计算2门学科求平均成绩的方法
    def avg(score1,score2):
        return(score1+score2)/2
   
    # 定义计算n门学科求平均成绩的方法
    def avg(*scores): #定义形参时,形参前加*号,表示可接收任意数量实参并将其置于一个元组中
        return sum(scores)/len(scores)  # 使用该形参时前面不需要加*号
   
    result = avg(98.2,88.1,70,65)
    print(result)    # 输出80.325
   
    scores=(88,89,90)
    result2 = avg(*scores)  # scores变量前必须加*解包,表示将元组各个元素分离出来,不然报错
    print(result2)
   
    # 例2:
    def test1(*args):       # 形参格式为:* + 形参名
        print(args)         # 输出多个参数的元组数据类型
   
    # 调用函数,不能关键字传值:
    test1(1,2,3,"xzh",18)     
    # 输出元组数据类型:
    (1,2,3,"xzh",18)`
   

   
   
    ```
   

#### 4.2 `**kwargs`

*   `**kwargs`接收类似关键参数一样显示赋值形式的多个实参并将其放入**字典**中
   
*   `**kwargs` 表示多参数传值,**号为关键格式,后面名称可随意改
   
    ```python
    `# 例1:
    def display(**employee):
            print(employee)
        
    emp={'name':'Tom','age':22,'job':'dev'}
   
    display(name='Tom', age=22, job='dev')  
    #输出结果:{name:'Tom',age:22, job:'dev'}
   
    display(**emp)   #输出结果:{'job':'dev','name':'Tom','age':22}   必须加**解包
   
    # 例2:
    def test2(**kwargs):    # 形参格式为:** + 形参名
        print(kwargs)       # 输出多个参数的字典数据类型
   
    # 调用函数,只能关键字传值:
    test2(name="Tom" , age=18 ,height=188.8)
    # 输出字典数据类型:
    {"name" : "Tom" ,  "age" : 18 , "height" : 188.8}`
   

   
   
    ```
   

总结:

*   单个*号表示使用元组传值,以元组形式传入的实参数不定
*   **号表示使用字典传值,以字典形式传入的实参数不定

### 5、普通参数和不定长数参的混合使用

```python
`# 例:
def test3(a,b,*args):
    print("输出a和b:" ,a,b)
    print("输出可变长度参数:" , args)

# 调用函数:
test3(1,2,3,4)

# 输出结果:
输出a和b:1 2
输出可变长度参数:(3,4)`



```

六、lambda表达式(匿名函数)
-----------------

主要用于编写简单逻辑的函数

*   lambda表达式可以用来声明匿名函数,即没有函数名字的临时使用的小函数。
*   lambda是一种以表达式形式生成函数的方法,和def语句类似用于创建一个函数。
*   def常用来设计功能复杂的一般性函数,而lambda用于简单的函数,以适应更灵活的应用,也被称为函数功能速写。
*   lambda定义的函数没有函数名,生成的是一个表达式形式的无名函数,表达式的结果是lambda的返回值。
*   lambda函数要传递给一个变量才可使用。

基本格式:

```python
`lambda 参数1,…,参数n : 函数体
# 例:
add = lambda  a,b,c:a+b+c
add(1,2,3)
# 若不需传参
f=lambda :pritn('hello')
f()`



```

例:

```python
`def hello(name):   
    prtin(name)
   
def add(x,y):   
    return x+y               

f= lambda name: print(name)     # 等价于没有函数名的hello()函数
f2=lambda x,y : x+y             # 等价于没有函数名的add()函数
f('Tom')   # 输出结果:打印出Tom
print(f2(5,3))  # 输出结果:8`




```

七、函数的委托(函数别名)
-------------

```python
`def add(x,y):
    return x+y

a = add  # 把函数当作对象传递给变量时注意不要加(),因为“函数名后+()”表示调用该函数

print(a(2,3))  # 该委托函数执行方法:a(),也就是a()相当于add()这个函数

#输出结果:5

def hello_chinese(name):
    print('你好',name)
   
hello = hello_chinese
hello('Tom')

hello = lanbda name:pritn('こんにちは', name)
hello('Tom')`


*   17


```

八、将函数作为另一函数的参数进行传递
------------------

```python
`#例1
def hello_chinese(name):
    print('您好:', name)

def hello_english(name):
    print('Hello', name)
   
def hello_japanese(name):
    print('こんにちは', name)
   
def hello(action,name):
    action(name)
   
hello(hello_chinese,"Tom")
hello(lambda name : print('Прывітанне!',name),"Tom")

#例2
l = list(range(1,21))
def add(x):
    return x+5
#将列表l中所有元素加5
result = list(map(add,l))
result = list(lambda x:x=5,l)`




```

九、实际应用
------

例:实现选择不同语言打招呼

```python
`# def hello_chinese(name):
#     print('您好:', name)

# def hello_english(name):
#     print('Hello', name)
   
# 初级写法
# while True:
#     name = input("请输入名称:n")
#     if name == 'stop':
#         break
#     language = input('请选择语言:n  c=> 中文版n e=>英文版n j=>日文版n')
#
#     if language == 'c':
#         hello_chinese(name)
#     elif language == 'e':
#         hello_english(name)
#     elif language == 'j':
#         (lambda name: print('こんにちは', name))(name)

# 中级写法
# while True:
#     name = input("请输入名称:n")
#     if name == 'stop':
#         break
#     language = input('请选择语言:n  c=> 中文版n e=>英文版n j=>日文版n')
#
#     if language == 'c':
#         action = hello_chinese
#     elif language == 'e':
#         action = hello_english
#     elif language == 'j':
#         action = lambda name: print('こんにちは', name)
#     action(name)  # 实现选择不同语言换对应的函数

#大神级写法
def hello_chinese(name):
    print('您好:', name)

def hello_english(name):
    print('Hello', name)
   
def hello_japanese(name):
    print('こんにちは', name)
      
operation{
    'e':hello_english,
    'c':hello_chinese,
    'j':hello_japanese,
    'r':lambda name : print('Прывітанне!',name)
}
   
while True:
    name = input("请输入名称:n")
    if name == 'stop':
        break
    language = input('请选择语言:n c=>中文版n e=>英文版n j=>日文版n r=>俄语版n')
    #operation.get(language)(name)  #若找不到key值则返回None,相当于None(name)会报错
    operation.get(language,hello_chinese)(name)  # 设默认值为hello_chinese 防止报错`




```

十、函数的高级工具
---------

### 1、`map()`函数

格式:

```python
`map(函数,可迭代的对象)
# map()返回的结果是一个map类型`

*   1
*   2


```

*   map()函数,顾名思义,用于映射,把一个序列的每一个元素映射到函数中,然后返回一个迭代对象。

例:

```python
`l = list(range(1,21))  # 生成1到20的列表l

result = []

# 将列表l中所有偶数放入列表result中
#方法1:使用循环
for n in l:
    if n % 2 == 0:
            result.append(n)
pritn(result)

#方法2:使用推导(实际开发过程中建议使用推导)
result = [x for x in l if x % 2 == 0]
pritn(result)

#将列表l中所有元素加5
#方法1:使用循环
for n in l:
    result.append(n+5)
pritn(result)

#方法2:使用推导
result =[x+5 for x in l]

#方法3:map()
def add(x):
    return x+5

result = list(map(add,l))
#或写成如下:
result = list(map(lambda n:n+5, l))`




```

### 2、`filter()`函数

格式:

```pyrhon
`filter(函数,可迭代对象)`

*   1


```

*   filter()函数,顾名思义,用于过滤,把一个序列的每个元素映射到函数中,返回结果为True的元素。

例:

```python
l = list(range(1,11))

def even_number(x):
    return x%2 == 0

res = list(filter(even_number,l))
# 或写成
res = list(filter(lambda x: x % 2== 0, l)) # 只留下能被2整除的元素
```

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马