嵌套函数(内部函数)
在函数内部定义的函数。inner()的定义和调用都在outer()函数内部,直接调用inner()函数报错,需要通过调用outer()函数,从而调用与其封装的inner()函数。
嵌套函数的特点:
- 封装- 数据隐藏
外部无法访问“嵌套函数”。 - 贯彻DRY(Don’t Repeat Yourself)原则
嵌套函数,可以让我们在函数内部避免重复代码。 - 闭包
# 以正确格式打印姓名
def printChineseName(name, familyName):
print("{0} {1}".format(familyName, name))
printChineseName("三", "张")
def printEnglishName(name, familyName):
print("{0} {1}".format(name, familyName))
printEnglishName("George", "Bush")
# 用嵌套函数实现
def printName(isChinese, name, familyName):
def inner_print(a, b):
print("{0} {1}".format(a, b))
if isChinese:
inner_print(familyName, name)
else:
inner_print(name, familyName)
printName(True, "三", "张")
printName(False, "George", "Bush")
nonlocal 关键字
nonlocal 用来声明外层的局部变量。
global 用来声明全局变量。
# 函数内部可调用全局变量,嵌套函数的内函数可以调用外层变量
x = 10
def outer():
a = 20
def inner():
print('x:', x)
print('inner:', a)
inner()
outer()
# 当函数内部要更改全局变量时,使用global关键字;当嵌套函数的内函数要更改外层函数定义的变量时,使用关键字nonlocal
x = 10
def outer():
a = 20
def inner():
global x
print('x:', x)
x = 100
nonlocal a
print('inner:', a)
a = 200
inner()
print('outer:', a)
print('x:', x)
outer()
LEGB 规则
Python 在查找变量名时,按照LEGB 规则查找:
Local --> Enclosed --> Global --> Built in
Local 指函数或者类的方法内部
Enclosed 指的是嵌套函数内部(一个函数包裹另一个函数,闭包)
Global 指的是模块中的全局变量
Built in 指Python内部的特殊名称
当某个变量映射在局部(local)命名空间中没有找到;接下来就会在闭包作用域(enclosed)进行搜索;如果闭包作用域也没有找到,就会到全局(global)命名空间中进行查找;如果任然没有,最后会在内建(built-in)命名空间搜索。当一个名称在所有命名空间中都没有找到,就会产生一个NameError报错。
面向对象初级
面向对象(Object oriented Programming,OOP)编程的思想主要是针对大型软件设计而来的。面向对象编程使程序的扩展性更强、可读性更好。
面向对象编程将数据和操作数据相关的方法封装到对象中,组织代码和数据的方式更加接近人的思维,从而大大提高了编程的效率。
Python 完全支持面向对象的基本功能,例如:继承、多态、封装等。Python 中,一切皆对象,数据类型、函数等,也都是对象。
面向对象和面向过程区别
- 面向过程(Procedure Oriented)思维
面向过程编程更加关注的是“程序的逻辑流程”,是一种“执行者”思维,从问题中找动词,适合简单、不需要协作的事务,来编写小规模的程序。
面向过程思想思考问题时,我们首先思考“怎么按步骤实现”,并将步骤对应成方法,一步一步,最终完成。
面向过程适合简单、不需要协作的事务。 - 面向对象(Object Oriented)思维
面向对象更加关注的是“软件中对象之间的关系”,是一种“设计者”思维,从问题中找名词,适合编写大规模的程序。
面向对象(Object)思想更契合人的思维模式,首先思考的是“拆分模块,怎么设计这个事物”,而不是“怎么按步骤实现”,是思维方式的转变。
面向对象可以帮助我们从宏观上把握、从整体上分析整个系统。但是,具体到实现部分的微观操作(就是一个个方法),仍然需要面向过程的思路去处理。面向过程和面向对象对是相辅相成的,面向对象离不开面向过程。 - 面向对象和面向过程的总结
面向对象和面向过程都是解决问题的思维方式,都是代码组织的方式。
解决简单问题可以使用面向过程
解决复杂问题:宏观上使用面向对象把握,微观处理上仍然是面向过程。
对象的进化
随着编程面临的问题越来越复杂,编程语言本身也在进化。从主要处理简单数据开始,
随着数据变多进化“数组”; 数据类型变复杂,进化出了“结构体”; 处理数据的方式和
逻辑变复杂,进化出了“对象”。
- 简单数据
像30,40,50.4 等数字,可以看做是简单数据,是最初计算机编程的主要数据。 - 数组
将同类型的数据放到一起,如整数数组[20,30,40],浮点数数组[10.2, 11.3, 12.4],字符串数组:[“aa”,”bb”,”cc”] - 结构体
将不同类型的数据放到一起,如C语言中的数据结构。
struct resume{
int age;
char name[10];
double salary;
};
- 对象
在结构体的基础上,将不同类型的数据、方法(即函数)都放到一起,形成对象。
类编码规则
- 类名首字母大写,多个单词之间采用驼峰原则。
- 实例名、模块名采用小写,多个单词之间采用下划线隔开。
- 每个类,应紧跟“文档字符串”,说明这个类的作用。
- 可以用空行组织代码,但不能滥用。在类中,使用一个空行隔开方法;模块中,使用两个空行隔开多个类。