本文是 Python 通用编程系列教程, 已全部更新完成, 实现的目标是从零基础开始到精通 Python 编程语言. 本教程不是对 Python 的内容进行泛泛而谈, 而是精细化, 深入化的讲解, 共 5 个阶段, 25 章内容. 所以, 需要有耐心的学习, 才能真正有所收获. 虽不涉及任何框架的使用, 但是会对操作系统和网络通信进行全局的讲解, 甚至会对一些开源模块和服务器进行重写. 学完之后, 你所收获的不仅仅是精通一门 Python 编程语言, 而且具备快速学习其他编程语言的能力, 无障碍阅读所有 Python 源码的能力和对计算机与网络的全面认识. 对于零基础的小白来说, 是入门计算机领域并精通一门编程语言的绝佳教材. 对于有一定 Python 基础的童鞋, 相信这套教程会让你的水平更上一层楼.
- # def: 定义函数的关键字
- # 函数名: 是用来调用函数的,
- # 函数名的命名必须能反映出函数的功能
- # 文档注释: 描述该函数, 来增强函数的可读性
- # 代码块: 函数的功能实现代码
- # return: 函数的返回值
- # print('========================')
- # print('hello Albert')
- # print('========================')
- # 1 先定义
- def print_sym(sym, count): # print_sym=<function print_msg at 0x000001B2A33698C8>
- print(sym * count)
- def print_msg(msg):
- print('\033[045m%s\033[0m' % msg)
- # 2 再调用(函数名加括号就是在调用函数)
- print(print_sym) # 函数名对应一个内存地址
- print_sym('#', 30)
- print_msg('hello Albert')
- print_sym('#', 30)
- # 关于函数的参数, 现在只需要知道定义的时候有几个参数, 调用的时候就传入几个参数.
- # 1 有参函数: 当函数体的功能依赖于传入的参数时, 我们就使用有参函数
- def max2(x, y): # x=100,=y101
- if x> y:
- print(x)
- else:
- print(y)
- max2(100, 101)
- # 2 无参函数: 当函数体的功能不使用传入的参数时, 我们传入参数显然是没有必要的
- def func():
- print('----------------------')
- print('---soft run-----------')
- print('----------------------')
- def interact():
- name = input('username>>:').strip()
- pwd = input('password>>:').strip()
- print(name, pwd)
- interact() # 定义时无参, 意味着调用时也无须传入参数
- func() # 定义时无参, 意味着调用时也无须传入参数
- # 3 空函数: 函数体为 pass, 事先定义功能组织结构, 通过调用函数执行某个功能
- def auth(username, password):
- """
- 这是一个用户认证功能, 在 Pycharm 中, 当输入三引号回撤之后, 下面的三行代码自动出现
- :param username:
- :param password:
- :return:
- """
- def put():
- """
- 上传功能
- :return:
- """
- pass
- def get():
- """
- 下载功能
- :return:
- """
- pass
- def ls():
- """
- list contents
- :return:
- """
- pass
- # 函数的使用必须遵循: 先定义, 后调用的原则
- # 注意: 如果没有事先定义函数而直接调用, 就相当于在引用一个不存在的变量名
- # 定义阶段: 在定义阶段只检测语法, 不执行函数体代码
- # 调用阶段: 根据函数名找到函数的内存地址, 然后执行函数体代码
- # 函数名加括号即调用函数
- # 定义阶段
- def foo():
- print('from foo')
- bar()
- def bar():
- print('from bar')
- # 调用阶段
- foo()
- """
- 会报错
- # 定义阶段
- def foo():
- print('from foo')
- bar()
- # 调用阶段
- foo()
- def bar():
- print('from bar')
- """
- # 1 基本的调用
- def func():
- print('from func')
- func()
- # 2 调用并把返回结果赋值给变量
- def max2(x, y):
- if x> y:
- return x
- else:
- return y
- res = max2(10, 3)
- print(res)
- res = max2(10, 3) * 100 # 和上面类似, 对返回结果再计算
- print(res)
- # 4 把返回结果再当做参数传入
- res = max2(max2(10, 3), 11)
- print(res)
- # 什么时候应该有返回值?
- # 函数体代码运行完毕后需要有一个返回结果给调用者
- # 1 没有 return, 或者 return 后面什么都不写, 返回值 None
- def func():
- pass
- def func1():
- return
- def func2():
- return None
- res = func()
- res1 = func1()
- res2 = func2()
- print(res)
- print(res1)
- print(res2)
- # 2 return 后跟一个值, 返回该值本身
- def func3():
- return 1
- res3 = func3()
- print(res3)
- # 3 return 可以逗号分隔, 返回多个值, 会返回一个元组给调用者
- def func4():
- return 1, 2, [1, 2, 3]
- res4 = func4()
- print(res4)
- def func5():
- print('first')
- return 1
- print('second')
- return 2
- print('third')
- return 3
- res5 = func5()
- print(res5)
- """
- 形参(形式参数): 指的是在定义函数时, 括号内定义的参数, 形参其实就变量名
- 实参(实际参数): 指的是在调用函数时, 括号内传入的值, 实参其实就变量的值
- """
- # x,y 是形参
- def func(x, y): # x=10,y=11
- print(x)
- print(y)
- # 10,11 是实参
- func(10, 11)
- """
- 注意:
- 实参值 (变量的值) 与形参 (变量名) 的绑定关系只在函数调用时才会生效 / 绑定
- 在函数调用结束后就立刻解除绑定
- """
- # 在定义函数时, 按照位置定义的形参, 称为位置形参
- def foo(x, y, z):
- print(x, y, z)
- """
- 注意:
- 位置形参的特性是: 在调用函数时必须为其传值, 而且多一个不行, 少一个也不行
- """
- # 在调用函数时, 按照位置定义的实参, 称为位置实参
- # foo(1,2) # 报错
- # foo(1,2,3,4) #报错
- foo(1, 3, 2) # x = 1, y = 3, z = 2
- """
- 注意: 位置实参会与形参一一对应
- """
- def foo(x, y, z):
- print(x, y, z)
- """
- 注意:
- 1 相当于直呼其名地为形参传值, 意味着即便是不按照顺序定义, 仍然能为指定的参数传值
- foo(2,1,3) # x=2,y=1,z=3
- foo(y=2,x=1,z=3) # x=1,y=2,z=3
- 2 在调用函数时, 位置实参与关键字实参可以混合使用, 但必须遵循形参的规则
- foo(1,z=3) # 报错
- 3 不能为同一个形参重复传值
- foo(1,x=1,y=3,z=2) # 报错
- 4 位置实参必须放到关键字实参的前面
- foo(y=3,z=2,1) # 报错
- """
- foo(1, z=3, y=2)
- # 1 定义阶段已经有值, 意味着调用阶段可以不传值
- def register(name, age, sex='male'):
- print(name, age, sex)
- register('Albert', 18, )
- register('James', 34, )
- register('林志玲', 20, 'female')
- register('周星驰', 50)
- # 2 位置形参必须在默认参数的前面
- # def func(y=1,x): #报错
- # pass
- # 3 默认参数的值只在定义阶段赋值一次, 也就是说默认参数的值再定义阶段就固定死了
- m = 10
- def foo(x, y=m):
- print(x, y)
- m = 'a' # foo 内的默认参数不会发生改变
- foo(1)
- foo(1, 11)
- # 4 默认参数的值应该设置为不可变类型(重要)
- # 假如默认参数不是不可变类型, 我们以列表为例
- def register(name, hobby, l=[]):
- l.append(hobby)
- print(name, l)
- register('Kobe', 'play')
- register('James', 'read')
- register('Albert', 'music')
- # 数据出错的原因就是每次掉用都会在同一个列表上作修改
- # 为了实现同样的功能, 修正后如下
- def register(name, hobby, l=None):
- if l is None:
- l = []
- l.append(hobby)
- print(name, l)
- register('Kobe', 'play')
- register('James', 'read')
- register('Albert', 'music')
- # 应用场景:
- # 对于经常需要变化的值, 需要将对应的形参定义成位置形参
- # 对于大多数情况值都一样的情况, 需要将对应的形参定义成默认参数
- # * 会将溢出的位置实参全部接收, 然后保存成元组的形式赋值给一个变量 args(可以任意命名, 约定俗成 args)
- def foo(x, y, z, *args): # args=(4,5,6,7,8)
- print(x, y, z)
- print(args)
- foo(1, 2, 3, 4, 5, 6, 7, 8, )
- # ** 会将溢出的关键字实参全部接收, 然后保存成字典的形式赋值给 kwargs
- def foo(x, y, z, **kwargs): # kwargs={'c':3,'a':1,'b':2}
- print(x, y, z)
- print(kwargs)
- foo(x=1, y=2, z=3, a=1, b=2, c=3)
- # 一旦碰到实参加 *, 就把该实参的值打散
- def foo(x, y, z, *args): # args=([4,5,6,7,8],)
- print(x, y, z)
- print(args)
- foo(1, 2, 3, *[4, 5, 6, 7, 8]) # foo(1,2,3,4,5,6,7,8)
- foo(1, 2, 3, *(4, 5, 6, 7, 8)) # foo(1,2,3,4,5,6,7,8)
- foo(1, 2, 3, *'hello') # foo(1,2,3,'h','e','l','l','o')
- def foo(x, y, z):
- print(x, y, z)
- # foo(*[1, 2, 3, 4]) # foo(1,2,3,4) #报错
- # foo(*[1, 2, ]) # foo(1,2,) #报错
- foo(*[1, 2, 3]) # foo(1,2,3)
- # 一旦碰到实参加 **, 就把该实参的值打散
- def bar(x, y, z, **kwargs):
- print(x, y, z)
- print(kwargs)
- bar(1, 2, 3, **{'a': 1, 'b': 2}) # foo(1,2,3,b=2,a=1)
- def boo(x, y, z):
- print(x, y, z)
- # boo(1, **{'z': 3, 'y': 2, 'x': 111}) # 报错 boo(1,z=3,y=2,x=111)
- boo(1, **{'z': 3, 'y': 2}) # foo(1,z=3,y=2)
- def index(name, age, gender):
- print('welcome %s %s %s' % (name, age, gender))
- def wrapper(*args, **kwargs): # args=(1,2,3),kwargs={'x':1,'y':2,'z':3}
- # print(args)
- # print(kwargs)
- index(*args, **kwargs) # index(*(1,2,3),**{'x':1,'y':2,'z':3}) # index(1,2,3,z=3,y=2,x=2)
- # wrapper(1,2,3,x=1,y=2,z=3) # 报错
- wrapper(name='Albert',age=18,gender='male')
- wrapper('Albert', age=18, gender='male')
- wrapper('Albert', 18, gender='male')
- wrapper('Albert', 18, 'male')
- """
- 执行过程:
- wrapper 的所有参数都传给 index, 而 index 函数只接收三个位置参数
- 星与星星的组合使用在源码中非常常见, 这也是装饰器的核心之一, 这非常重要.
- """
来源: https://www.cnblogs.com/mayite/p/10652470.html