6、函数

1、自定义函数

函数(Functions)是指可重复使用的程序片段。它们允许你为某个代码块赋予名字,允许你通过这一特殊的名字在你的程序任何地方来运行代码块,并可重复任何次数。这就是所谓的调用(Calling)函数。

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()
  • 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
  • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明
  • 函数内容以冒号起始,并且缩进。
  • return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的 return 相当于返回 None。
  • return 可以返回多个值,此时返回的数据为元组类型
  • 定义参数时,带默认值的参数必须在无默认值参数的后面

定义函数的语法格式:

# 定义函数时,带默认值的参数必须在无默认值的参数后面
def function_name(param1, param2, param3=None, param4=2):
    body

2、参数传递

在Python中,类型属于对象,变量没有类型

a = [1, 2, 3]
a = "Runoob"

以上代码中,[1,2,3] 是 List 类型,"Runoob" 是 String 类型,而变量 a 是没有类型,它仅仅是一个对象的引用(一个指针),可以是指向 List 类型对象,也可以是指向 String 类型对象。

可更改与不可更改对象:

在Python中,字符串,数字和元组是不可更改的对象,而列表、字典则是可以修改的对象。

不可变类型:

变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。

可变类型:

变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。

Python 函数的参数传递:

不可变类型:

类似 c++ 的值传递,如整数、字符串、元组。如fun(a),传递的只是 a 的值,没有影响 a 对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。

可变类型:

类似 c++ 的引用传递,如列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响

Python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。

3、参数

必须参数

必须参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。

关键字参数

关键字参数和函数调用关系密切,函数调用使用关键字参数来确定传入的参数值。使用关键字参数允许函数调用时参数的顺序与声明不一致,因为Python解释器能够用参数名匹配参数值。

# 函数定义
def print_info(name, age):
    "打印任何传入的字符串"
    print("名字: ", name)
    print("年龄: ", age)
    return

# 函数调用
print_info(age=50, name="john")  # 关键字参数,参数的顺序可以改变

默认参数

调用函数时,如果没有传递参数,则会使用默认参数。

# 函数定义
def print_info(name, age=35):
    print ("名字: ", name)
    print ("年龄: ", age)
    return

# 函数调用   
print_info(age=50, name="john")
print("------------------------")
print_info(name="john")  # age 使用默认参数 35

不定长参数

  • 加了星号 * 的参数会以元组的形式导入,存放所有未命名的变量参数。
  • 如果在函数调用时没有指定参数,他就是一个空元组,我们也可以不向函数传递未命名的变量。
def print_info(arg1, *vartuple):	# vartuple是一个元组,用于存放函数调用时,传入的多余的参数
    print("输出: ")
    print(arg1)
    for var in vartuple:
        print (var)
    return

print_info(10)
print_info(70, 60, 50)
  • 加了两个星号 * 的参数会以字典的形式导入。变量名为键,变量值为字典元素值
def print_info(arg1, **vardict):
    print("输出: ")
    print(arg1)
    print(vardict)

print_info(1, a=2, b=3)

4、匿名函数

Python 使用 lambda 来创建匿名函数。

所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。lambda 只是一个表达式,函数体比 def 简单很多。

lambda 的主体是一个表达式,而不是一个代码块。仅仅能在 lambda 表达式中封装有限的逻辑进去。 lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。 虽然 lambda 函数看起来只能写一行,却不等同于 CC++ 的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。

# 语法格式
lambda [arg1 [,arg2,.....argn]]: expression

lambda 函数的返回值是其expression表达式的值。

calc = lambda x,y: x/y if x>y else x*y  # 匿名函数最多只支持三元运算,再复杂的判断不支持
 
print(calc(3,8))
print(calc(16,8))
print(func(3,8))
print(func(16,8))

5、函数注释

Python 3 提供一种语法,用于为函数声明中的参数和返回值附加元数据。下面的例子是注解后的版本,特点在第一行:

def clip(text : str, max_len : 'int > 0' = 80) -> str:
    """
    	在max_len前面或后面的第一个空格处截断文本 
    """
    end = None
    if len(text) > max_len:
        space_before = text.rfind(' ', 0, max_len)
        if space_before >= 0
            end = space_before
        else:
            space_after = text.rfind(' ', max_len)       # 返回字符串最后一次出现的位置,没有则返回-1 
            if space_after >= 0:
                end = space_after
    if end is None:        # 没找到空格
        end = len(text)
    return text[:end].rstrip()        # 删除字符串末尾指定的字符串,默认为空格
  1. 函数声明中的各个参数可以在后增加注解表达式(如text : str)。

  2. 如果参数由默认值,注解放在参数名和 = 号之间(如max_len : 'int > 0' = 80)。

  3. 如果注解有返回值,在 ) 和函数末尾的之间增加 -> 和一个表达式。那个表达式可以是任何类型。注解中最常用的类型是类(如 strint)和字符串(如 'int > 0')。

注解不会做任何处理,只是存储在函数的annotations属性(一个字典)中:

>>> from clip_annot import clip
>>> clip._annotations__
{
     'text' : <class 'str'>, 'max_len' : 'int > 0', 'return' : <class 'str'>}

'return'键保存的是返回值注解,即函数声明里以 -> 标记的部分。

Python对注解所做的唯一的事情是,把他们存储在函数的__annotations__属性里。仅此而已,Python不做检查,不做强制,不做验证,什么操作都不做

换句话,注解对Python解释器没任何意义。注解只是元数据,可以供IDE、框架和装饰器等工具使用。

你可能感兴趣的:(#,Python,基础)