跟我一起学python-自定义函数

luckyFang 2021年10月12日 12次浏览

跟我一起学python-自定义函数

定义函数

def funcName(parmaList):
  funcBody
  • def define function定义函数关键字
  • funcName 函数名称
  • paramList形式参数列表
    • 无参数
    • 位置参数
    • 默认参数
    • 可变参数
  • funcBody 函数体

那就手动定义一个函数叭

def say_hello():
  print("Hello,World!")

调用函数

那么如何调用函数呢?

func_name(paramList)
  • func_name 函数名
  • paramList 实际参数列表
say_hello()

Hello,World!

函数返回值

无返回值

调用函数不返回任何值

def funcName():
  pass

单个返回值

调用函数返回一个值

def funcName():
  x = 10
	return x

返回多个值

python支持多个返回值 以元组方式传递

def funcName():
  a=10,b=20
  return a,b

函数参数

实际参数和形式参数

其实就是我们常说的,形参和实参

如何区分?

实际参数: 就是本质上的参数

形式参数: 函数调用时传递过来的参数

# 这里的 name 是形式参数
def say_hello(name):
  print("Hello,",name)
  
# 调用函数 这里的 “jack” 是实际参数

say_hello("jack")

那么下来看下这个代码

def modify(var):
    var = 10

a = 20
modify(a)
print(a)

运行结果是多少?

20? 10 ? 答案是:20

python中不可变对象作为函数参数传递时,形参改变,实参不受影响

如何验证?

def modify(var):
    var = 10
    print(id(var))


a = 20
print(id(a))
modify(a)
print(a)

4378254224
4378253904
20

通过上面代码看到 两个变量的地址是不一样的


那我们再试试可变对象

def modify_list(lst):
    lst.append(1)
    print("after:",id(lst))


lst = []
print("before:",id(lst))
modify_list(lst)
print(lst)

这里就不卖关子了,直接看运行结果

before: 4819946368
after:  4819946368
[1]

由此可见,可变对象形参改变,实参也会跟着变

位置参数

所谓位置参数就可指定参数位置(好一个废话文学)

def max(a, b):
    if a > b:
        return a
    return b

# 传统调用
print(max(10, 20))

# 指定位置
print(max(b=20, a=10))
20
20

默认参数

所谓默认参数,说的是函数调用时没有传递参数,或传递参数不全,函数从采用默认值的一种约束

def say_hello(name="world!", n=1):
    print("-"*20)
    for i in range(n):
        print("Hello", name)

# 输出两遍 jack
say_hello("jack", 2)

# 参数不全 采用默认参数 输出一遍
say_hello("jack")
# 没有传递参数 则输出 Hello world!
say_hello()
--------------------
Hello jack
Hello jack
--------------------
Hello jack
--------------------
Hello world!

可变参数

可变参数就是:参数的数量不确定 在python中默认以元组方式传递

语法说明

def funcName(*args):
  pass

对于可变参数 用 在参数前面加个*

def sum(*args):
    print("args:", args)
    s = 0
    for item in args:
        s += item
    return s


# 参数个数不确定
print(sum(1, 2, 3))
print(sum(1, 2, 3, 4, 5))

args: (1, 2, 3)
6
args: (1, 2, 3, 4, 5)
15

还有一种:以字典传递的可变参数

参数前面加两个*

def settings(**kw):
    if kw["debug"] == True:
        print(kw)
    print("配置加载完毕")


settings(port="8080", host="localhost", debug=True)
{'port': '8080', 'host': 'localhost', 'debug': True}
配置加载完毕

不难发现 key: 是参数名称 val: 是参数值

__main__

python中有一个比较特殊的内置变量__name__

只有正常执行当前脚本文件时__name__的值为__main__

但是第三方导入使用脚本内函数时___name__的值就不为__main__

if __name__ == '__main__':
    print("Hello,World!")

借助这个特性可以为脚本设置 main 函数

__file__

file 内置变量会记录当前运行的python文件

print(__file__)

/Users/luckyfang/PycharmProjects/pyStudy/func.py

__doc__

doc内置变量会记录当前脚本的头部注释信息

'''
这里是注释
'''

print(__doc__)

这里是注释

实践下吧

编写一个函数,统计一段话中有多少大写字母 小写字母 数字.

方案1

for 循环遍历 通过内置函数判断

def analyze(raw_str):
    lower_count=upper_count=digit_count=0
    for ch in raw_str:
        if ch.islower():
            lower_count+=1
        if ch.isupper():
            upper_count+=1
        if ch.isdigit():
            digit_count+=1
    return lower_count,upper_count,digit_count


print(analyze("Python python 123 哈哈哈"))
(11, 1, 3)

方案2

通过range生成序列访问字符串下标,然后判断范围

def analyze(raw_str):
    lower_count = upper_count = digit_count = 0
    for i in range(len(raw_str)):
        if raw_str[i] >= 'a' <= 'z':
            lower_count += 1
            continue
        if raw_str[i] >= 'A' <= 'Z':
            upper_count += 1
            continue
        if raw_str[i] >= '0' <= '9':
            digit_count += 1
            continue
    return lower_count, upper_count, digit_count


print(analyze("Python python 123 哈哈哈"))

方案3

正则表达式实现,需要导入正则表达式模块

import re

def analyze(raw_str):
    digit_count = len(re.findall(r'[0-9]',raw_str))
    lower_count = len(re.findall(r'[a-z]',raw_str))
    upper_count = len(re.findall(r'[A-Z]',raw_str))
    return lower_count,upper_count,digit_count

print(analyze("Python python 123 哈哈哈"))