Python 基础之函数与代码复用(三)

在前面的学习中,其实我们已经接触到了一些函数,比如:

        type()   函数能返回数据的类型;

        len()     函数能返回数据的长度;

        print()   函数能在控制台将内容输出出来;

        range() 函数能生成整数数列;

1. 函数的概念

函数是一段具有特定功能的,可重用的语句组,用函数名来表示并通过函数名进行完成功能调用。

函数也可以看作是一段具有名字的子程序,可以在需要的地方调用执行,不需要再每个执行地方重复编写这些语句。每次使用函数可以提供不同的参数作为输入,以实现对不同数据的处理;函数执行后,还可以以反馈相应的处理结果。

函数是一种功能抽象,有以下两个特点:

  • 可以具体完成某个功能
  • 可以重复使用

2. Python 中函数的定义

Python 定义一个函数使用 def 关键字,语法形式如下:

def <函数名>(<参数列表>):

	<函数体>

	return <返回值列表>

案例

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

print(add(x=3,y=4))
运行结果: 7

案例1

def demo():

    return '这是:demo'

print(demo())

运行结果: 这是:demo

案例2

def add():

    return 'dmeo'

print(add)

运行结果: 
含义:调用函数时,没有添加括号。因此 返回的是对象地址

函数不加括号
一、不带括号时,调用的是这个函数本身 ,是整个函数体,是一个函数对象,不须等该函数执行完成;
二、带括号(参数或者无参),调用的是函数的执行结果,须等该函数执行完成的结果;

3. 函数的调用过程

程序调用一个函数需要执行以下四个步骤:

  1. 调用程序在调用处暂停执行;
  2. 在调用时将实参赋值给函数的形参;
  3. 执行函数体语句;
  4. 函数调用结束给出返回值,程序回到调用前的暂停处继续执行;

4. 函数的参数

  • 形式参数:函数定义时候的参数;
  • 实际参数:函数调用时候的参数;
def add(x,y): # x,y是形参,它只是一个变量名,供函数体中的代码调用。

    return x + y

print(add(x=3,y=4)) # x=3,y=4是实参。它是实际的数据,会传递给形参,供函数体执行。

4.1 形参

定义函数时,形参根据功能不同,可以定义几种类型。

4.1.1 必须参数

在定义函数时,如果要求调用者必须传递实参给这个形参,它就是必须参数。

直接定义在函数名后的()中的形参就是必须参数。

错误案例:

def add(x,y): # 定义了两个形参

    return x + y

print(add(x=3)) # 只传入了1个实参。看看调用有啥问题?

运行结果:
TypeError: add() missing 1 required positional argument: 'y'
含义:缺少一个必须的位置参数;

正确案例:

def add(x,y): # x,y是形参

    return x + y

print(add(x=3,y=113)) # x=3,y=113是实参

运行结果: 116

4.1.2 默认参数

在定义函数时,某些形参有可能在调用时不用接收实参,这种情况可以定义为默认参数。

在函数名后()中,以参数名=默认值的形式定义的形参就是默认参数。

注意:默认参数必须定义在必须参数的后面

案例:

def add(x,y=12): # x,y是形参,但是y设置了默认形参12

    return x + y

print(add(x=3)) # x=3实参。只传入1个实参就能调用函数啦!

运行结果: 15

案例1:

def add(x=20,y=12): # x,y是形参,但是x,y都设置了默认参数;

    return x + y

print(add()) # 调用时不用传入函数就能调佣成功!

运行结果: 32

4.1.3 不定参数

在定义函数时,不确定在调用时会传递多少个实参时,可以定义不定参数。

位置不定参

在函数名后的()中,在形参前加 *号可以定义位置不定参,通常它会定义为 *args

它用来接收函数调用时,以位置参数传递过来的超过形参数量的多余的实参。

注意:不订参必须定义在默认参数后面;

位置不定参数会将所有多余的位置实参创建成元组。

案例:

def add(x,*args): # x是形参;

    return x , args

print(add(1,2,3,4,5,6,6,7,8,9,10)) # 调用函数时多传入几个参数!

运行结果: (1, (2, 3, 4, 5, 6, 6, 7, 8, 9, 10))
含义: 实参 1 对应形参的x,其他多余的参数 创建成元组;

案例1:

def add(x,y, *args): # x,y是形参;

    return x + y, args

print(add(10,20,3,4,5,6,6,7,8,9,10))

运行结果: (30, (3, 4, 5, 6, 6, 7, 8, 9, 10))
含义: 调用函数时传入的实际参数10,20对应的是形参的x,y 其他多余的参数会创建成元组;

关键字不定参

在函数名后的()中,在形参前加 **号可以定义关键字不定参,通常它会定义为 **kwargs

它用来接收函数调用时,以关键字参数传递过来的超过形参数量的多余的实参。

注意:不定参必须定义在默认参数后面;

关键字不定参数会将所有多余的关键字实参创建成字典。

def add(x,y, **kargs): # x,y是形参;

    return x + y, kargs

print(add(x=10,y=20,a=3,v=4,s=5,r=6))

运行结果: (30, {'a': 3, 'v': 4, 's': 5, 'r': 6})
含义: 调用函数时x,y是位置参数,意思就是和形参的x,y 一一对应的。
其他多余的参数就是位置不定参。会创建成字典;

4.2 实参

调用函数是传递实参有两种方式。

4.2.1 位置参数

调用函数时,传递实参时默认会按照形参的位置一一对应,这种实参传递叫做位置参数。

案例

def add(x,y): # x,y 是行参,

    return x / y # 返回 结果

print(add(4,2)) # 调用函数时传入了 两个参数。4对应 x, 2对应 y。
运行结果: 2.0

print(add(2,4)) # 调用函数时传入了 两个参数。2对应 x, 4对应 y。
运行结果: 0.5

4.2.2 关键字参数

调用函数时,传递实参时以形参名=实参的形式传递参数,叫做关键字参数。

这是不用考虑参数的位置。

注意:关键字参数必须写在位置参数后面。

案例

def add(x,y): # x,y 是行参,

    return x / y # 返回 结果

print(add(x=4,y=2)) # 调用函数时传入了 两个参数。4对应 x, 2对应 y。
运行结果: 2.0

print(add(x=2,y=4)) # 调用函数时传入了 两个参数。2对应 x, 4对应 y。
运行结果: 0.5

案例1

def add(x,y):

    return x / y

print(add(x=4,2))
运行结果: SyntaxError: positional argument follows keyword argument
含义:关键字参数要在位置参数前面。


def add(x,y):

    return x / y

print(add(2,y=4))
运行结果: 0.5

def add(x,y):

    return x / y

print(add(2,x=4))
运行结果: TypeError: add() got multiple values for argument 'x'
含义: 实参2 应该对应着 形参x,但是实参4 有对应着 形参x,所以报错信息是 形参x接受了多个参数;

4.2.3 *,**在传递实参时的用法

解包

在传递实参时,可以通过*对迭代对象进行解包。

def add(x,y,*args):

    return x , y,args

ls = [1,2,3,4,5,6]
print(add(*ls))
运行结果: (1, 2, (3, 4, 5, 6))
含义: 调用函数时 实参1传给形参x,参数2传给形参y,多余的参数 创建成元组;

** 解包

在传递实参时,可以通过**对字典对象进行解包。

def add(x,y,**kwargs):

    return x,y,kwargs

ls ={'x':3,'y':4,'v':2,'t':5,'u':6}
print(add(**ls))
运行结果: (3, 4, {'v': 2, 't': 5, 'u': 6})
含义: 调用函数时 实参3传给了形参x,实参4传给了形参y,其他多余的参数,创建成字典;

4.3 return返回值

函数还有一个很重要的功能就是返回结果。

Python 中使用 return 关键字来退出函数,返回到函数被调用的地方继续往下执行。

return 可以将0个,1个,多个函数运算完的结果返回给函数被调用处的变量。

函数可以没有返回值,也就是说函数中可以没有 return 语句,这时函数返回 None,

例如上面我们定义的那些函数。

大白话就是:就像主管向下级员工下达命令,让其去打印文件,员工打印好文件后并没有完成任务,还需要将文件交给主管。

return 会将多个返回值以元组的形式返回。

案例

def add(x,y,*args):

    print(x, y, args)
    return x,y,args
    
ls = ['a','b','v','y','h']
print(add(*ls))
运行结果: 
a b ('v', 'y', 'h') # 这个是 print 返回的结果;
('a', 'b', ('v', 'y', 'h')) # 这个是 return 返回的结果;
可以看一下,使用return返回的结果,用括号包括起来的,print返回的结果,并没有使用括号包括;

print 和 return 返回的结果有什么不同?

Python中的 print 和 return 都可以用来将结果输出到控制台或其他地方,但它们的作用和用法有所不同。

print 用于将结果输出到控制台,它不会返回任何值,只是将结果打印出来供用户查看;

return 用于将结果返回给调用者,它会直接结束函数并返回一个值;

因此,print 和 return 的主要区别在于它们的作用和用法。

print用于将结果输出到控制台。

return用于将结果返回给调用者。

5. lambda函数

lambda 函数是 Python 中的一种匿名函数,它可以在一行代码中定义简单的函数,通常用于一些简单的函数或作为函数的参数传递。

语法格式如下:

lambda arguments: expression

案例

add = lambda k,y : k * y
print(add(12,5))
运行结果: 60

可以这样理解 lambda 表达式,其就是简单函数(函数体仅是单行的表达式)的简写版本。相比函数,lamba 表达式具有以下  2 个优势:

  • 对于单行函数,使用 lambda 表达式可以省去定义函数的过程,让代码更加简洁;
  • 对于不需要多次复用的函数,使用 lambda 表达式可以在用完之后立即释放,提高程序执行的性能。

6. 变量作用域

Python 中一个变量能够被访问的范围叫做作用域。作用域简单的分为全局变量和局部变量。

6.1 全局变量

Python 是解释型编程语言,解释器在运行一个 Python 程序时会在计算机内存中申请一块内存用来运行这个程序。

全局变量在这块内存空间中都可以被访问和修改。

直接定义在函数外的变量就是全局变量,在程序运行的全过程有效。

案例

name = '演示' # 这是 全局变量,所有的函数都能调用;

def demo():
    print(name)
demo()
运行结果: 演示


def demo1():
    print(name)
demo1()
运行结果: 演示

6.2 局部变量

定义在函数里的变量就是局部变量,它只在它定义的函数里起作用,一旦函数执行完毕它就不存在了。

案例

def demo():
   name = '演示' # 这是局部变量,只能在当前函数里面被调用;
   return name
print(demo())
运行结果: 演示

def demo1():
    print(name)
demo1()
运行结果: NameError: name 'name' is not defined
含义:局部变量在函数外部不能直接访问;

6.3 global关键字

使用 global 关键字可以在函数内部修改全局变量;

案例

def demo():
   global name # 把 name 变量修改成全局变量;
   name = '演示'
   test1 = 123 # test1是 内部变量;
   return name,test1 # 返回 name,test1 的值;
print(demo())
运行结果: ('演示', 123)


def demo1():
    print(name) # 打印出 name 的值
    print(test1) # 内部变量 test1 未设置成全局变量。
demo1()
运行结果: 演示
NameError: name 'test1' is not defined

7. Python内建函数

Python 解释器提供了70多个内置函数。

import builtins
print(dir(builtins))


['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'ModuleNotFoundError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'breakpoint', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']

8. 常用内建函数

8.1 print

打印传入对象的字符串形式;

  • print(value,..,sep=' ', end='\n')
    • value 会打印value的字符串形式
    • sep 分隔符,当有多个value时默认用空格作为分割
    • end 每次打印在最后默认添加回车换行符
print(1,2,3)
运行结果: 1 2 3

print(2,3,4,5,sep='.')
运行结果: 2.3.4.5


print(1,2,3,4,end='')
print(5)
运行结果: 1 2 3 45

8.2 input

接收用户的输入数据,以字符串的形式返回。

可以接收字符串参数最为提示信息输出;

print(input('请输入数字:'))

8.3 type

返回object的类型;

print(type('test'))
运行结果: 

8.4 dir

返回传入对象的所有属性和方法名的列表;

print(dir(str))
运行结果: 输出 字符串的所有方法;

8.5  help

返回内建对象的帮助信息;

pass

8.6 len

返回容器的元素个数;

ls = [1,2,3,4,5,6,0]
print(len(ls))
运行结果: 7

8.7 hash

返回对象的hash值;

print(hash('w'))
运行结果: -9199666568396213368

8.8 id

返回传入对象的身份id(虚拟内存地址的整数形式);

print(id(1))
运行结果: 4390496768

8.9 range

  • range(stop) -> range object
  • range(start, stop[,step])

返回一个range对象,产生整数序列;

你可能感兴趣的:(Python,python)