Python笔记_第三篇_面向对象_1.面向对象的基本概念和作用域
1. 软件编程的实质:
软件编程就是将我们的思维转变成计算机能够识别语言的一个过程。重要的是思想,代码技术反而次要。因此思想也是最难的,突破固定的思想是关键
2. 什么是面向过程:
* 自上而下顺序执行,逐步求精。
* 程序结构是按照功能划分成若干个基本模块,这也是一种树状结构。
* 各个模块之间的关系尽可能简单,在功能上又相对独立。
* 每一个模块内部结构是由顺序、选择、循环三种基本结构。
* 模块化实现的方法是使用子程序。
* 程序流程是在写程序时就已经决定了。
3. 什么是面向对象?
* 把数据及其对数据的操作方法放在一起,成为一个整体(对象)。
* 对同类对象抽象出共性,形成类。
* 类中的大多数数据,只能用本类方法进行处理。
* 类通过一个简单的外部链接与外界发生关系,对象和对象之间通过消息进行通信。
* 流程程序由用户在使用中决定。
4. 什么是对象?
一切皆对象!
5. 理解面向对象:
* 面向对象是相对于面向过程而言的。
* 面向对象和面向过程都是一种思想。
* 面向过程:
强调的是功能行为。
关注的是解决问题需要哪些步骤。
* 面向对象:
将功能封装进对象,强调了具备功能的对象。
关注的是解决问题需要哪些对象。
* 面向对象是基于面向过程的。
6. 面向对象的特点:
* 一种符合人们思考习惯的思想。
* 可以将复杂的事情简单化。
* 将程序员从执行者转换为指挥者。
* 完成需求时:
先要根据所需功能的对象来用。
如果该对象不存在,那么创建一个具有所有功能的对象。
7. 类与对象的关系:
* 使用计算机语言就是不断的在描述现实生活中的事物。
* Python中描述事物通过类的体现,类是具体事物概念给予的定义。
* 对象即该类的事物,实实在在存在的个体。
8. 类的定义:
* 生活中描述事物无非就是描述事物的名称/属性和行为/方法。
如:人有身高、体重等属性,还有说话,打架等行为。
* Python中使用类来描述事物也是如此。
属性:对应类中的成员变量。
方法:对于类中的成员行为。
* 定义类其实就是定义类中的成员(成员变量和成员方法)
* 拥有相同(或者类似)属性和方法的对都可以。
9. 类的设计:
只关心三样东西:
事物名称(类名):人(Person)
属性:身高(height)、年龄(age)
行为(功能):跑(run)、打架(fight)
10. 作用域:
作用域:变量可以使用的范围。程序变量并不是所有位置都能使用,访问权限决定了变量在哪里赋值。
作用域分:局部作用域、嵌套作用域、全局作用域、内建作用域,分别对应的字母是LEGB。
前面在讲函数的时候也是具有一种作用域的概念,因此在这里和类一起讲。
10.1 变量的作用域LEGB:
在Python程序中创建、改变、查找变量名时,都是在一个保存变量名的空间中进行,我们称之为命名空间,也被称之为作用域。python的作用域是静态的,在源代码中变量名被赋值的位置决定了该变量能被访问的范围。即Python变量的作用域由变量所在源代码中的位置决定。
10.2 高级语言对数据类型的使用过程。
一般的高级语言在使用变量时,都会有下面4个过程。当然在不同的语言中也会有着区别。
- 声明变量:让编辑器知道有这一个变量的存在
- 定义变量:为不同数据类型的变量分配内存空间
- 初始化:赋值,填充分配好的内存空间
- 引用:通过引用对象(变量名)来调用内存对象(内存数据)
10.3 作用域的产生。
就作用域而言,Python与C有着很大的区别,在Python中并不是所有的语句块中都会产生作用域。只有当变量在Module(模块)、Class(类)、def(函数)中定义的时候,才会有作用域的概念。看下面的代码:
def func():
variable =
print variable
print variable #代码的输出为:
NameError: name 'variable' is not defined
在作用域中定义的变量,一般只在作用域中有效。 需要注意的是:在if-elif-else、for-else、while、try-except\try-finally等关键字的语句块中并不会产成作用域。看下面的代码:
if True:
variable =
print (variable)
print ("******")
print (variable)
# 100 ****** 100
所以,可以看到,虽然是在if语句中定义的variable变量,但是在if语句外部仍然能够使用。
10.4 作用域的类型:
在Python中,使用一个变量时并不严格要求需要预先声明它,但是在真正使用它之前,它必须被绑定到某个内存对象(被定义、赋值);这种变量名的绑定将在当前作用域中引入新的变量,同时屏蔽外层作用域中的同名变量。
L(local)局部作用域
局部变量:包含在def关键字定义的语句块中,即在函数中定义的变量。每当函数被调用时都会创建一个新的局部作用域。Python中也有递归,即自己调用自己,每次调用都会创建一个新的局部命名空间。在函数内部的变量声明,除非特别的声明为全局变量,否则均默认为局部变量。有些情况需要在函数内部定义全局变量,这时可以使用global关键字来声明变量的作用域为全局。局部变量域就像一个 栈,仅仅是暂时的存在,依赖创建该局部作用域的函数是否处于活动的状态。所以,一般建议尽量少定义全局变量,因为全局变量在模块文件运行的过程中会一直存在,占用内存空间。
注意:如果需要在函数内部对全局变量赋值,需要在函数内部通过global语句声明该变量为全局变量。
E(enclosing)嵌套作用域
E也包含在def关键字中,E和L是相对的,E相对于更上层的函数而言也是L。与L的区别在于,对一个函数而言,L是定义在此函数内部的局部作用域,而E是定义在此函数的上一层父级函数的局部作用域。主要是为了实现Python的闭包,而增加的实现。
G(global)全局作用域
即在模块层次中定义的变量,每一个模块都是一个全局作用域。也就是说,在模块文件顶层声明的变量具有全局作用域,从外部开来,模块的全局变量就是一个模块对象的属性。
注意:全局作用域的作用范围仅限于单个模块文件内
B(built-in)内置作用域
系统内固定模块里定义的变量,如预定义在builtin 模块内的变量。
10.5 变量名解析LEGB法则:
搜索变量名的优先级:局部作用域 > 嵌套作用域 > 全局作用域 > 内置作用域
LEGB法则: 当在函数中使用未确定的变量名时,Python会按照优先级依次搜索4个作用域,以此来确定该变量名的意义。首先搜索局部作用域(L),之后是上一层嵌套结构中def或lambda函数的嵌套作用域(E),之后是全局作用域(G),最后是内置作用域(B)。按这个查找原则,在第一处找到的地方停止。如果没有找到,则会出发NameError错误。
举例1:
def func():
variable =
print variable variable =
func() #
print variable #
举例2:
variable =
def test_scopt():
print variable #variable是test_scopt()的局部变量,但是在打印时并没有绑定内存对象。
variable = #因为这里,所以variable就变为了局部变量
test_scopt()
print variable
举例3:全局变量 global
a =
b = [, ] def func():
global a
a =
print "in func a:", a
b[] =
print "in func b:", b if __name__ == '__main__':
print "before func a:", a
print "before func b:", b
func()
print "after func a:", a
print "after func b:", b
举例4:globals() 函数:
这个函数会以字典类型返回当前位置的全部局部变量。
>>>a='runoob'
>>> print(globals()) # globals 函数返回一个全局变量的字典,包括所有导入的变量。
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'a': 'runoob', '__package__': None}
上面的例子会报出错误,因为在执行程序时的预编译能够在test_scopt()中找到局部变量variable(对variable进行了赋值)。在局部作用域找到了变量名,所以不会升级到嵌套作用域去寻找。但是在使用print语句将变量variable打印时,局部变量variable并有没绑定到一个内存对象(没有定义和初始化,即没有赋值)。本质上还是Python调用变量时遵循的LEGB法则和Python解析器的编译原理,决定了这个错误的发生。所以,在调用一个变量之前,需要为该变量赋值(绑定一个内存对象)。
注意:为什么在这个例子中触发的错误是UnboundLocalError而不是NameError:name ‘variable’ is not defined。因为变量variable不在全局作用域。Python中的模块代码在执行之前,并不会经过预编译,但是模块内的函数体代码在运行前会经过预编译,因此不管变量名的绑定发生在作用域的那个位置,都能被编译器知道。Python虽然是一个静态作用域语言,但变量名查找是动态发生的,直到在程序运行时,才会发现作用域方面的问题
Python笔记_第三篇_面向对象_1.面向对象的基本概念和作用域的更多相关文章
- Python笔记_第三篇_面向对象_4.单下划线和双下划线
说道这里我们需要稍微暂停一下.前面我们说到了类是作为一个对象存放容器.这个容器里面有属性和方法.最好的理解类的方式就是把类想想成一个容器. 然后构造了一个析构函数和构造函数,然后又对object和se ...
- Python笔记_第三篇_面向对象_2.第一个Python类
1. 设计一个类: 设计一个类主要从三个方面进行考虑: 第一:类名:类名要见名知意.首字母大写. 第二:属性. 第三:方法. 备注:在Python中有些东西并不是绝对化的事情,有些根据Python社区 ...
- Python笔记_第三篇_面向对象_9.Python中的"get"和"set"方法(@property和@.setter)
1. 限制访问的问题: 如果学过C# 语言的我们可以知道C# 语言有get和set方法.我们之前想要获取父类中的私有变量,只能通过写一个set和get的函数进行访问或者通过类生成的新关键字来访问私有属 ...
- Python笔记_第三篇_面向对象_2.构造函数和析构函数(含self说明)
1. 构造函数: 为什么要有构造函数? 打一个比方:类的创建就是好比你创建了好了一种格式的房间,你租给上一个住户的后,里面会对方很多“垃圾”和不规则的物品摆放.构造函数就是下一个住户再使用的时候进行物 ...
- Python笔记_第三篇_面向对象_5.一个关于类的实例(人开枪射击子弹)
1. 我们学了类的这些东西,用这些类我们来操作一个关于类的实例. 2. 题目:人开枪射击子弹,然后具有装弹动作,然后再开枪. 第一步:设计类: 人类名:Person属性:gun行为:fire,fill ...
- Python笔记_第三篇_面向对象_3.重载(overloading)和重写(overriding)
1. 重载: overloading:就是将函数重新定义一遍. 1.1 __str__( )和__repr__( )的重载: 格式: __str__( ):在调用print打印对象时自动调用,是给用户 ...
- Python笔记_第三篇_面向对象_8.对象属性和类属性及其动态添加属性和方法
1. 对象属性和类属性. 我们之前接触到,在类中,我们一般都是通过构造函数的方式去写一些类的相关属性.在第一次介绍类的时候我们把一些属性写到构造函数外面并没有用到构造函数,其实当时在写的时候,就是在给 ...
- Python笔记_第三篇_面向对象_7.多态
1. 多态的概念 多态:一种事物的多种形态.其表现形式就是连续的继承关系. 还以人喂食动物的例子.最终目标是人可以喂食任何一种动物.如果人要喂食100多种动物,难道要写100中方法吗?多态就是把属性和 ...
- Python笔记_第三篇_面向对象_6.继承(单继承和多继承)
1. 概念解释: 继承:有两个类:A类和B类.那么A类就拥有了B类中的属性和方法. * 例如:Object:是所有类的父亲,还可以成为基类或者超类(super()) * 继承者为子类,被继承者成为父类 ...
随机推荐
- 【转载】RobotFramework的Setup或Teardowm中执行多个关键字
有时候需要在setup和teardowm中执行多个关键字 以前的做法就是重新封装一个keyword,然后调用,It’s OK 这里介绍另外一个方法,使用Run Keywords来实现 用法其实非常的简 ...
- 【Android】家庭记账本手机版开发报告四
一.说在前面 昨天 对界面显示和逻辑结构进行完善 今天 1.添加菜单(查询.清除所有等) 2.使用滑动删除 问题 1.在做查询时获取SearchView时引 入包错误经过长时间的尝试后才修正 2.滑动 ...
- 大数据高可用集群环境安装与配置(08)——安装Ganglia监控集群
1. 安装依赖包和软件 在所有服务器上输入命令进行安装操作 yum install epel-release -y yum install ganglia-web ganglia-gmetad gan ...
- Mac系统Snail SVN 精简版配置比较、合并工具:Beyond Compare及破解
Mac系统 Beyond Compare及破解 前言 在上一篇文章:Mac系统的SVN客户端:Snail SVN 精简版 介绍了在mac系统中svn客户端使用的是snail svn,但是当我想要把本地 ...
- 算法设计和分析(Prim算法构建最小生成树)
问题: 给定无向图G(N,M)表明图G有N个顶点,M条边,通过Prim算法构造一个最小生成树 分析: 算法流程: 构造好的最小生成树就是step6 运行代码: #include<cstdio&g ...
- DQL多表查询
DQL多表查询 一.多表查询实现多个表之间查询数据 1.交叉连接笛卡尔积:A表中的每一行匹配B表中的每一行基本结构:select [数据库名1.]表名1,属性名1,......, [数据库名.]表名. ...
- org.springframework.test.context.junit4.SpringJUnit4ClassRunner
项目中有了spring-test的依赖,里面确实也有 org.springframework.test.context.junit4.SpringJUnit4ClassRunner 此类,但是项目就是 ...
- python3.4+Django+pymysql
pip install Pymysql 修改app里面的__init__.py import pymysqlpymysql.install_as_MySQLdb()
- Windbg 大改版,值得期待
早上从twitter上面看到一篇文章,看到windbg会提供一个Time Travel Debugging(TTD) 功能,该功能会在未来的版本引入. Time travel debugging: I ...
- React编写组件的局部样式
我们都知道,在Vue的单文件组件中,style标签中编写的样式默认为全局样式,如果我们想编写局部样式, 使用一个scoped关键字就可以. 那么在React中怎么实现呢? (注: 这种方法必须使用类选 ...