函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数能提高应用的模块性,和代码的重复利用率。
函数的定义
- 函数以
def
关键词开头,后接函数名和圆括号()。 - 函数执行的代码以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回
None
。
例:使用函数来输出"Hello World!":
def hello() :
print("Hello World!")
hello()
函数的调用
函数的基本结构完成以后,你可以通过另一个函数调用执行,也可以直接从 Python 命令提示符执行。
# 定义函数
def printme( str ):
# 打印任何传入的字符串
print (str)
return
# 调用函数
printme("我要调用用户自定义函数!")
printme("再次调用同一函数")
函数参数
- 位置参数 (positional argument)
- 默认参数 (default argument)
def printinfo(name, age=8):
print('Name:{0},Age:{1}'.format(name, age))
printinfo('小马') # Name:小马,Age:8
printinfo('小马', 10) # Name:小马,Age:10
- 可变参数 (variable argument)
- 关键字参数 (keyword argument)
#可写函数说明
def printme( str ):
"打印任何传入的字符串"
print (str)
return
#调用printme函数
printme( str = "天池龙珠计划")
- 命名关键字参数 (name keyword argument)
- 参数组合
变量作用域
- Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。
- 定义在函数内部的变量拥有局部作用域,该变量称为局部变量。
- 定义在函数外部的变量拥有全局作用域,该变量称为全局变量。
- 局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。
【例子】
def discounts(price, rate):
final_price = price * rate
return final_price
old_price = float(input('请输入原价:')) # 98
rate = float(input('请输入折扣率:')) # 0.9
new_price = discounts(old_price, rate)
print('打折后价格是:%.2f' % new_price) # 88.20
- 当内部作用域想修改外部作用域的变量时,就要用到
global
和nonlocal
关键字了。
闭包
- 是函数式编程的一个重要的语法结构,是一种特殊的内嵌函数。
- 如果在一个内部函数里对外层非全局作用域的变量进行引用,那么内部函数就被认为是闭包。
- 通过闭包可以访问外层非全局作用域的变量,这个作用域称为 闭包作用域。
Lambda 表达式
匿名函数的定义
在 Python 里有两类函数:
- 第一类:用
def
关键词定义的正规函数 - 第二类:用
lambda
关键词定义的匿名函数
Python 使用 lambda
关键词来创建匿名函数,而非def
关键词,它没有函数名,其语法结构如下:
lambda argument_list: expression
-
lambda
- 定义匿名函数的关键词。 -
argument_list
- 函数参数,它们可以是位置参数、默认参数、关键字参数,和正规函数里的参数类型一样。 -
:
- 冒号,在函数参数和表达式中间要加个冒号。 -
expression
- 只是一个表达式,输入函数参数,输出一些值。
注意:
如,在 filter
和map
函数中的应用:
-
expression
中没有 return 语句,因为 lambda 不需要它来返回,表达式本身结果就是返回值。 - 匿名函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
- 匿名函数 常常应用于函数式编程的高阶函数 (high-order function)中,主要有两种形式:
- 参数是函数 (filter, map)
- 返回值是函数 (closure)
-
filter(function, iterable)
过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用list()
来转换。
类与对象
对象 = 属性 + 方法
对象是类的实例。换句话说,类主要定义对象的结构,然后我们以类为模板创建对象。类不但包含方法定义,而且还包含所有实例共享的数据。
- 封装:信息隐蔽技术
我们可以使用关键字 class
定义 Python 类,关键字后面紧跟类的名称、分号和类的实现。
- 继承:子类自动共享父类之间数据和方法的机制
- 多态:不同对象对同一方法响应不同的行动
类、类对象和实例对象
类对象:创建一个类,其实也是一个对象也在内存开辟了一块空间,称为类对象,类对象只有一个。
class A(object):
pass
实例对象:就是通过实例化类创建的对象,称为实例对象,实例对象可以有多个
基本的魔法方法
-
__init__(self[, ...])
构造器,当一个实例被创建的时候调用的初始化方法 -
__new__(cls[, ...])
在一个对象实例化的时候所调用的第一个方法,在调用__init__
初始化前,先调用__new__
。 -
__new__
至少要有一个参数cls
,代表要实例化的类,此参数在实例化时由 Python 解释器自动提供,后面的参数直接传递给__init__
。 -
__new__
对当前类进行了实例化,并将实例返回,传给__init__
的self
。但是,执行了__new__
,并不一定会进入__init__
,只有__new__
返回了,当前类cls
的实例,当前类的__init__
才会进入。 - 若
__new__
没有正确返回当前类cls
的实例,那__init__
是不会被调用的,即使是父类的实例也不行,将没有__init__
被调用 -
__new__
方法主要是当你继承一些不可变的 class 时(比如int, str, tuple
), 提供给你一个自定义这些类的实例化过程的途径。 __str__(self)
:- 当你打印一个对象的时候,触发
__str__
- 当你使用
%s
格式化的时候,触发__str__
-
str
强转数据类型的时候,触发__str__
__repr__(self)
:-
repr
是str
的备胎 - 有
__str__
的时候执行__str__
,没有实现__str__
的时候,执行__repr__
-
repr(obj)
内置函数对应的结果是__repr__
的返回值 - 当你使用
%r
格式化的时候 触发__repr__
算术运算符
-
__add__(self, other)
定义加法的行为:+
-
__sub__(self, other)
定义减法的行为:-
-
__mul__(self, other)
定义乘法的行为:*
-
__truediv__(self, other)
定义真除法的行为:/
-
__floordiv__(self, other)
定义整数除法的行为://
-
__mod__(self, other)
定义取模算法的行为:%
-
__divmod__(self, other)
定义当被divmod()
调用时的行为 -
divmod(a, b)
把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)
-
__pow__(self, other[, module])
定义当被power()
调用或**
运算时的行为 -
__lshift__(self, other)
定义按位左移位的行为:<<
-
__rshift__(self, other)
定义按位右移位的行为:>>
-
__and__(self, other)
定义按位与操作的行为:&
-
__xor__(self, other)
定义按位异或操作的行为:^
-
__or__(self, other)
定义按位或操作的行为:|
生成器
用生成器实现斐波那契数列
def libs(n):
a = 0
b = 1
while True:
a, b = b, a + b
if a > n:
return
yield a
for each in libs(100):
print(each, end=' ')
# 1 1 2 3 5 8 13 21 34 55 89