Python—③Python面向对象

Python—③Python面向对象

<<<CSDN排版不美观,想看排版美观的进Python—③Python面向对象>>>

1、Python面向对象(Object Oriented,OO)

①面向对象(Object Oriented,OO)与面向过程(Procedure Oriented)
面向对象(Object Oriented,OO)是把数据及对数据的操作方法放在一起,作为一个相互依存的整体——对象。面向对象将功能封装进对象,强调具备了功能的对象;面向对象关注的是解决问题需要哪些对象
面向过程(Procedure Oriented) 可以理解成自上而下顺序执行,逐步求精;它是其程序结构是按功能划分为若干个基本模块,这些模块形成一个树状结构;面向过程强调的是功能行为;它关注的是解决问题需要哪些步骤

②类和对象
类是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用
特征相当于类的属性
行为相当于类的方法
类相当于一个模板,或者说是一张图纸,而对象就是根据这个模板或者这张图纸(即类)创建出来的一个具体的实物
先有类,再有对象

类的三要素
类名:类名满足大驼峰命名法(每个单词首字母都大写)
属性:该类事物具有什么样的特征
方法:该类事物具有什么样的行为

dir内置函数
其实Pyhton中变量、数据、函数等都是对象,两个方法验证:
1、在该 标识符 后输入一个 . ,看PyCharm会不会提示有方法,或者在iPython中按下Tab键,是否提示有方法
2、使用内置函数dir传入该 标识符,可以查看对象内所有属性及方法

提示: 方法名 格式的方法是Python提供的内置方法或属性

new >>> 创建对象时,会被自动调用
init >>> 对象被初始化时,会被自动调用
del >>> 对象被从内存中销毁前,会被自动调用
str >>> 返回对象的描述信息,print函数输出使用
提示:利用好dir函数,有很多内容就不需要死记硬背。

定义类(与Java类似)
class 类名:
def 方法名(self,参数列表):

创建对象
对象名=类名()

面向对象中的引用概念
Python中使用类创建对象之后,对象名指向的是对象在内存中的地址,即对象名指向了对象的地址
如果使用print函数输出对象名,可以看到该对象名引用的对象来自于哪一个类,以及在内存中的地址(十六进制)
%d可以以十进制输出数字;%x可以以十六进制输出数字

方法中的self参数
给对象设置属性,可以直接 对象名.属性=“值” (但是不推荐使用,作为了解;因为属性最好包含在类的内部)
self指的是当前这个对象,要访问该对象的属性,可以 self.属性;要访问该对象的属性,可以 self.方法

__init__初始化方法
当使用类名() 创建对象时,会自动执行以下操作:
1、为对象在内存中分配空间——创建对象 2、为对象属性设置初始值——初始化方法(init)
init 初始化方法,是对象的内置方法;__init__方法是专门用来定义一个类具有哪些属性的方法
即创建对象后会自动执行初始化方法,用来定义一个类具有哪些属性的

在__init__方法内部,写 self.属性名=“初始化值” ,就可以给对象的属性赋有初始值
步骤:
1、在__init__方法中使用 self.属性名=“初始化值”
2、创建对象时使用类名(属性1、属性2…)

__del__方法
对象创建后在空间分配完内存后,就会自动调用__init__方法
当一个对象在内存中被销毁前,会自动调用__del__方法
如果希望对象在被销毁前,执行一些代码,则可以放入__del__方法中

__str__方法
在Python中直接输出对象名时,默认会输出 该对象由哪一个类创建以及在内存中的地址(十六进制)
如果在开发中,希望使用print输出对象变量时,能够打印自定义内容,就可以利用__str__内置方法
注意:__str__方法需要返回字符串

③面向对象之封装
封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别;将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成“类”,其中数据和函数都是类的成员。
简而言之,即将属性和方法封装到一个抽象的类中;然后外界调用时,直接由该类创建对象,然后直接通过 对象.方法 解决问题,而不需要关系对象方法的细节在类中是怎样的;同一类创建的多个对象的属性互不干扰

如果定义属性值,不知道设置什么初始值时,可以将值设置为 None ,任何变量都可以设置为 None
判断一个变量值是否为None,需用到身份运算符
is >>> is是判断两个标识符是不是引用同一个对象 >> x is y,类似id(x)==id(y)
is not >>> is not是判断两个标识符是不是引用不同对象 >> x is not y,类似id(x)!=id(y)
is 与 == 区别:
is用于判断两个变量引用对象是否是同一个
== 用于判断引用变量的值是否相等
结论:在Python中针对None比较时,建议用 is 判断,这也是PEP8的规范要求

私有属性和私有方法
在实际开发中,对象的某些属性或方法 可能只有对象的内部使用,而不希望被外部访问到,这时候就可以私有,也可以保证一定的安全性
私有属性即 对象 的属性不希望被外界访问到方法
私有方法即 对象 的属性不希望被外界访问到的方法
私有属性将属性前加上 __ ,即两个英文下划线,就定义成了私有属性,外界不能访问,只能在本类中访问
私有方法将属性前加上 __ ,即两个英文下划线,就定义成了私有方法,外界不能访问,只能在本类中访问

伪私有属性和伪私有方法
提示:在日常开发中,不要使用这种方式访问对象的 私有属性 和 私有方法
Python在对 私有属性 和 私有方法处理时,实际是对名字进行了特殊的处理,使得外界无法访问
处理方式:_类名__属性名或方法名
用 对象._类名__属性名或方法名 就可以访问到私有属性和私有方法了

④面向对象之继承
继承是面向对象软件技术当中的一个概念,与多态、封装共为面向对象的三个基本特征。 继承可以使得子类具有父类的属性和方法或者重新定义、追加属性和方法等。
继承:子类拥有父类的所有 属性和方法

继承的语法:
class 类名(父类名):

子类继承父类后,然后再根据子类自己的特性,封装子类自己特有的方法

继承中的专业术语(了解):
假设有两个类 Animal类 和 Dog类,Animal类是父类,Dog类是子类
我们称Dog类是Animal的子类,Animal是Dog类的父类,Dog类从Animal类继承
我们也称Dog类是Animal的派生类,Animal类是Dog类的基类,Dog类从Animal类派生

继承的传递性
C类从B类继承,B类又从A类继承
那么C类就具有A类和B类的所有属性和方法
即子类拥有父类以及父类的父类中封装的所有属性和方法

方法的重写override
如果在开发中,子类的方法实现和父类的方法实现不同,就可以使用重写(也叫复写或覆盖),在子类中 重新编写 父类的方法
实现:在子类中定义一个与父类方法名相同的函数
在运行时,如果调动该方法,就只会调用子类重写的方法,而不会调用父类的方法

另外也有一种应用场景:
子类的方法是在父类的方法有扩展,即父类原本封装的方法实现是子类方法的一部分
这时就可以在子类复写父类方法中,在需要的位置使用 super().父类方法 来调用父类的方法,然后再根据需求写子类特殊的部分
(这个和Java中稍微不同,Java规定 super.父类方法 必须写在子类方法的第一行,而Python无此规定;而且Java是 super.父类方法 ,在Python是 super().父类方法 )
在Python中,super是一个特殊的类,super() 可以看成是 super类 创建出来的对象

扩展:
在Python2.x中,如果需要调用父类的方法,还可以使用一下方式:
父类名.方法(self)
在目前Python3.x 还支持该方法,但是不推荐,因为一旦父类发生变化,方法调用位置的类名同样需要修改

继承中,父类的私有属性和私有方法
子类对象 不能再自己的内部直接访问父类的 私有属性 或 私有方法
解决:子类对象 通过父类的共有方法简介访问到 私有属性 和 私有方法

多继承
子类继承一个父类的情况叫做单继承
当子类拥有多个父类时 就叫多继承
多继承语法
class 子类名(父类名1,父类名2…)

多继承的使用注意事项
如果父类之间存在同名的属性或方法,应该避免使用多继承

提问:如果不同的父类中存在相同的方法名,子类在调用时,会调用哪一个父类中的方法呢?
回答:会按照继承的顺序,依次先在自己本类中找,接着按继承的顺序在父类中找,最后再object类中找

MRO——方法搜索顺序
Python中针对类提供了一个内置属性__mro__,可以查看方法搜索顺序
MRO是 method resolution order,主要用于在多继承时判断方法、属性的调用路径
使用:类.mro

新式类与旧式类(经典类)
object是Python为所有对象提供的基类,提供有一些内置的属性和方法,可以使用 dir函数 查看
新式类:以object为基类的类,推荐使用
经典类:不以object为基类的类,不推荐使用
在Python3.x中定义类时,如果没有指定父类,会默认使用 object 作为该类的基类——Python3.x中定义的类都是新式类
在Python2.x中定义类时,如果没有指定父类,则不会以 object 作为基类
新式类和经典类在多继承时——会影响到方法的搜索顺序
为了保证编写的代码能同时在Python2.x和Python3.x中运行
所以在定义类如果没有父类,建议统一继承自object
class 类名(object)

⑤面向对象之多态
封装 将 属性和方法 封装到一个抽象的类中,以保证整体性和安全性
继承 可以实现代码的复用,相同的代码不需要反复的编写
多态 不同的子类对象调用相同的父类方法,产生不同的结果,增加代码的扩展性与灵活性
多态即同一个行为具有多个不同表现形式或形态的能力

类对象
在Python中,可以将类看成是特殊的对象,即类对象
在程序运行时,类对象在内存中只有一个,使用一个类可以创建出多个对象实例
类也有自己的属性和方法,我们叫做类属性和类方法,通过 类名. 的方式可以访问类的属性或者调用类的方法

类属性就是给 类对象 定义的属性,通常用于记录与这个类有关的特征,类属性不会用于记录具体对象的特征
类属性的获取可以理解成一个 向上查找机制
当调用 对象.属性 时,首先会在对象内部查找对象属性,如果没有,就向上看有没有该名字的类属性
因此访问类属性可以:1、类名.类属性 2、对象.类属性(不推荐)
注意:如果使用 对象.类属性=值 赋值语句,只会给对象添加一个属性,而不会影响到类属性的值
类属性就是类对象定义的属性,使用赋值语句在class关键字下方可以定义类属性,类属性通常用于记录这个类的相关特征

类方法
类方法就是针对类对象定义的方法
在类方法内部可以直接访问类属性或者调用其他的类方法
@classmethod
def 类方法名(cls):

修饰器 @classmethod 用来告诉解释器这是一个类方法的,传的第一个参数应该为 cls
cls标识由哪一个类调用的方法,方法内的cls就是哪一个类的引用
提示:不过使用其他名称也可以,不过习惯使用的是 cls ,通过 类名. 调用类方法时,不需要传递cls参数
在方法内部,可以通过 cls. 访问类的属性,也可以通过 cls. 调用其他类方法

静态方法
在开发时,如果需要在类中封装一个方法,这个方法:
既不需要访问实例属性或者调用实例方法、也不需要访问类属性或者调用类方法,就可以将该方法封装成静态方法
@staticmethod
def 静态方法名():

小结:
当方法内部需要访问实例属性时就用实例方法,实例方法内部可以使用 类名. 访问类属性
方法内部只需要访问类属性就使用类方法
方法内部不需要访问实例属性和类属性
如果方法内部既需要访问实例属性,又需要访问类属性,应该定义成实例方法,当访问类属性可以使用 类名.

⑤单例设计模式
设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的
单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例
比如 任务管理器、音乐播放器、回收站 等等,都是单例设计模式的应用

__new__方法
使用类名()创建对象时,Python解释器首先会调用__new__方法为对象分配空间
new 是一个由object基类提供的内置静态方法,主要作用有:
1、在内存中为对象分配空间
2、返回对象的引用
Python解释器获得对象的引用后,将引用作为第一个参数,传递给 init 方法
重写 new 方法得注意,一定要 return super().new(cls),否则Python解释器得不到分配了空间的对象引用,将不会调用对象的初始化方法,其中 super().new(cls) ,这其中的 cls 即为创建的是哪个类,所以为cls
注意:new 是一个静态方法,在调用时需要主动传递 cls 参数

单例模式Python定义步骤
1、定义一个类属性,初始值为 None,用于记录单例对象的引用
2、重写 new 方法
3、如果类属性 is None ,调用父类方法分配空间,并在类属性中记录结果
4、返回类属性中记录的对象引用

在每次使用类名()创建对象时,Pyhton的解释器都会自动调用两个方法:
new 分配空间
init 对象初始化
让 __new__方法每次调用都只返回第一次被创建对象的引用,按上述定义步骤可以实现,但是还存在 初始化方法会被再次调用
解决步骤:
1、定义一个类属性 init_flag 标记是否执行过初始化动作,初始值为False
2、在 __init__方法中,判断 init_flag,如果为False就执行初始化动作
3、然后将 init_flag 设置为 True
4、这样再次自动调用 __init__方法时,初始化动作就不会被再次执行了

⑥异常
程序在运行时,如果Python遇到一个错误,会停止程序执行,并且提示一些错误信息,这就是异常
程序停止执行并且提示错误信息的动作,我们称之为 抛出(raise)异常

所以可以通过 异常捕获 可以针对突发事件做集中处理,从而保证程序的稳定性和健壮性
语法:
try:
尝试执行的代码(可能会出错的代码)
except:
处理错误
try 尝试下方的代码,不确定是否能够正常执行代码;except 如果不是,下方编写尝试失败的代码
错误类型捕获
如果遇到不同类型的异常,需要做针对性处理
语法:
try:
尝试执行的代码(可能会出错的代码)
except 错误类型1:

except(错误类型2,错误类型3):

except Exception as result:
print(“未知错误 %s” % result)
当Python解释器抛出异常时,最后一行错误信息的第一个单词,就是错误的类型

捕获未知错误
在开发中,要预判到所有可能出现的错误,有一定的难度
如果希望希望程序无论出现任何错误,都不会因为Python解释器抛出异常而被终止,可以再增加一个except
语法:
except Exception as result:
print(“未知错误 %s” % result)

完整格式:
try:
尝试执行的代码(可能会出错的代码)
except 错误类型1:

except 错误类型2:

except(错误类型3,错误类型4):

except Exception as result:
print(“未知错误 %s” % result)
else:

没有异常才会执行的代码


finally:

无论如何都会执行的代码

异常的传递
当函数执行出现异常,会将异常传递给函数的调用一方
如果传递到主程序,仍然没有异常处理,程序才会被终止
提示:
在开发中,可以在主函数中增加异常捕获,如果主函数在调用其他函数出现异常,都会传递到主函数的异常捕获中,这样就不需要在代码中,增加大量的异常捕获,能够保证代码的整洁性

抛出raise异常
除了代码执行错误Python解释器会抛出异常之外,还可以根据应用程序特有的业务需求抛出异常
Python中提供了一个Exception异常类,在开发时,如果满足特定的业务需求时,希望抛出异常,步骤:
1、创建一个Exception对象
2、使用raise关键字抛出异常对象
比如根据用户输入密码,不符合规范,则抛出异常
exception=Exception(“您输出的密码不符合规范”)
raise exception

⑦模块
模块是Python程序架构的一个核心概念
每一个以扩展名为 py 结尾的Python源代码文件都是一个模块
模块名同样也是一个标识符,需要符合标识符的命名规则
在模块中定义的全局变量、函数、类都是提供给外界直接使用的工具
模块就好比Java的工具包一样,想要使用该工具包的工具,就先需要导入该工具包,即先导入该模块
导入语法:
1、import 模块名1,模块名2
2、import 模块名1
import 模块名2
推荐导入多个模块时使用第二种语法
通过 模块名. 使用模块提供的工具——全局变量、函数、类

如果模块名字过长或者过于复杂,则可以使用 as 指定模块的别名
import 模块名1 as 模块别名
注意:模块别名应该符合大驼峰命名法

from …import 导入
如果希望从一个模块中,导入部分工具,就可以使用from … import的方式
import 模块名是一次性把模块中所有工具全部导入
from 模块名1 import 工具名
导入之后,不需要通过 模块名. ,可以直接使用模块提供的工具——全局变量、函数、类
注意:如果两个模块,存在同名的函数,那么后导入模块的函数,将会覆盖掉先导入的函数。开发时import代码应该统一写在代码顶部,更容易及时发现冲突;一旦发现冲突,也可以使用 as 关键字给其中一个工具起一个别名

from …import * 导入 (导入所有工具)
这种方式不推荐,因为函数重名并没有任何提示,出现问题不方便排插

模块的搜索顺序以及__file__属性
Python的解释器在导入模块时,会
1、搜索 当前目录 指定模块名的文件,如果有就直接导入
2、如果没有,再搜索系统目录
在开发时,给文件起名,不要和 系统的模块崇宁
Python中每一个模块都有一个内置属性 file 可以查看模块的完整路径
如果当前目录有个 xxx.py,导入该 xxx.py 模块时,会先加载当前目录下的 xxx.py ,而不会加载系统中的 xxx.py

模块扩展
一个独立的Python文件就是一个模块
在导入文件时,文件中所有没有任何缩进的代码都会被执行一遍
name 属性
name 属性可以做到,测试模块的代码,只在测试情况下被运行,而在被导入时不被执行
name 是Python的一个内置属性,记录这一个字符串
如果是被其他文件导入的,name 就是模块名
如果是当前执行的程序,name 就是 main
一般开发中会看到下列格式的代码:
def main():

if name==“main”:
main()

⑧包(Package)
包是一个包含多个模块的特殊目录
目录下有一个特殊的文件 init.py
PyCharm新建 Python Package,会自动帮你生成__init__.py文件
包名的命名方式和变量名一样,小写字母+_

好处:使用import 包名 可以一次性导入包中所有的模块

要在外界使用包中的模块,需要在__init__.py中指定对外界提供的模块列表
从当前目录导入模块名语法:
from . import 模块名1
from . import 模块名2

发布模板
制作发布压缩包步骤:
1、创建setup.py
from distutils.core import setup

setup(name=“包名”, # 包名
version=“1.0”, # 版本
description=“描述信息”, # 描述信息
long_description=“完整描述信息”, # 完整描述信息
author=“作者”, # 作者
author_email=“作者邮箱”, # 作者邮箱
url=“主页”, # 主页
py_modules=[“包名.模块名1”,
“包名.模块名2”])

有关字典参数的详细信息,可以参阅官方网站:https://docs.python.org/2/distutils/apiref.html
2、构建模块
python3 setup.py build
3、生成发布压缩包
python3 setup.py sdist
注意:要制作哪个版本的模块,就是用哪个版本的解释器执行

安装模块
$ tar -zxvf 模块名
$ sudo python3 setup.py install

卸载模块
直接从安装目录下,把安装模块的目录删除就可以了(file 属性可以查看模块的完整路径)
cd /usr/local/lib/python3.7/dist-packages/
sudo rm -r 模块名*

pip安装第三方模块
第三方模块通常是指由知名的第三方团队开发的并且被程序员广泛使用的Python 包 / 模块
例如 pygame 就是一套非常成熟的 游戏开发模块
pip 是一个现代的,通用的 Python 包管理工具
提供了对 Python 包的查找、下载、安装、卸载等功能
安装和卸载命令如下:

将模块安装到 Python 2.x 环境

$ sudo pip install pygame
$ sudo pip uninstall pygame

将模块安装到 Python 3.x 环境

$ sudo pip3 install pygame
$ sudo pip3 uninstall pygame

⑧文件操作
计算机操作文件的步骤一般是:1、打开文件 2、读/写文件 3、关闭文件
操作文件
open >>> 打开文件,并且返回文件操作对线
read >>> 将文件内容读取到内存
write >>> 将制定内容写入文件
close >>> 关闭文件
open函数负责打开文件,并且返回文件对象
read/write/close三个方法都需要通过文件对象来调用

open函数
open函数的第一个参数是要打开的文件名(区分大小写)
1、如果文件存在,返回文件操作对象
2、如果文件不存在,会抛出异常
read方法可以一次性读入并返回文件的所有内容
close方法负责关闭文件

操作文件

打开文件

file = open(“文件名”)

读取文件内容

text = file.read()
print(text)

关闭文件

file.close()

文件指针
文件指针标记从哪个位置开始读取数据;第一次打开文件时,通常文件指针会指向文件的开始位置;当执行了read方法后,文件指针会移动到读取内容的末尾;默认情况下会移动到文件末尾
如果执行了一次read方法,读取完了所有内容,那么在此调用read方法,将不能获取到内容了,因为文件指针已经移动到了文件末尾
注意:
1、如果忘记关闭文件,会造成系统资源消耗,而且会影响到后序对文件的访问
2、方法执行后,会把文件指针移动到文件末尾

打开文件的方式
open函数默认以只读方式打开文件,并且返回文件对象
语法:
file = open(“文件名”,“访问方式”)

访问方式 说明
r 以只读方式打开文件。文件的指针将会放在文件的开头,这是默认模式。如果文件不存在,抛出异常
w 以只写方式打开文件。如果文件存在会被覆盖。如果文件不存在,创建新文件
a 以追加方式打开文件。如果该文件已存在,文件指针将会放在文件的结尾。如果文件不存在,创建新文件进行写入
r+ 以读写方式打开文件。文件的指针将会放在文件的开头。如果文件不存在,抛出异常
w+ 以读写方式打开文件。如果文件存在会被覆盖。如果文件不存在,创建新文件
a+ 以读写方式打开文件。如果该文件已存在,文件指针将会放在文件的结尾。如果文件不存在,创建新文件进行写入
注意:频繁的移动文件指针,会影响文件的读写效率,开发中更多的时候会以 只读、只写 的方式来操作文件

按行读取文件内容
read方法默认会把文件的所有内容一次性读取到内存;而且如果文件太大,对内存的占用会非常严重
readline方法 可以一行一行读取内容,方法执行后,会把文件指针移动到下一行,准备再次读取

打开文件

file = open(“文件名”)
while True:
# 读取一行内容
text = file.readline()
# 判断是否读到内容
if not text:
break
# 每读取一行的末尾已经有了一个 \n
print(text, end="")
# 关闭文件
file.close()

复制文件
用代码的方式,来实现文件复制过程
小文件复制步骤:
打开一个已有文件,读取完整内容,然后写入到新文件中

1. 打开文件

file_read = open(“源文件名”)
file_write = open(“新文件名”, “w”)

2. 读取并写入文件

text = file_read.read()
file_write.write(text)

3. 关闭文件

file_read.close()
file_write.close()

大文件复制步骤:
打开一个已有文件,逐行读取内容,然后按顺序写入到新文件中

1. 打开文件

file_read = open(“源文件名”)
file_write = open(“新文件名”, “w”)

2. 读取并写入文件

while True:
# 每次读取一行
text = file_read.readline()

# 判断是否读取到内容
if not text:
    break

file_write.write(text)

3. 关闭文件

file_read.close()
file_write.close()

文件/目录常用管理操作
在 终端 / 文件浏览器、 中可以执行常规的 文件 / 目录 管理操作,例如:创建、重命名、删除、改变路径、查看目录内容等等
在 Python 中,如果希望通过程序实现上述功能,需要导入 os 模块

文件操作
序号 方法名 说明 示例
01 rename 重命名文件 os.rename(源文件名, 目标文件名)
02 remove 删除文件 os.remove(文件名)

目录操作
序号 方法名 说明 示例
01 listdir 目录列表 os.listdir(目录名)
02 mkdir 创建目录 os.mkdir(目录名)
03 rmdir 删除目录 os.rmdir(目录名)
04 getcwd 获取当前目录 os.getcwd()
05 chdir 修改工作目录 os.chdir(目标目录)
06 path.isdir 判断是否是文件夹 os.path.isdir(判断源)

文本文件的编码格式
文本文件存储的内容是基于 字符编码 的文件,常见的编码有 ASCII 编码,UNICODE 编码等
Python 2.x 默认使用 ASCII 编码格式
Python 3.x 默认使用 UTF-8 编码格式
ASCII 编码
计算机中只有 256 个 ASCII 字符
一个 ASCII 在内存中占用 1 个字节 的空间
8 个 0/1 的排列组合方式一共有 256 种,也就是 2的8次方

UTF-8 编码格式
计算机中使用 1~6 个字节 来表示一个 UTF-8 字符,涵盖了 地球上几乎所有地区的文字
大多数汉字会使用 3 个字节 表示
UTF-8 是 UNICODE 编码的一种编码格式

Python 2.x 使用中文
在 Python 2.x 文件的 第一行 增加以下代码,解释器会以 utf-8 编码来处理 python 文件

- coding:utf8 -(这方式是官方推荐使用的)

也可以使用:# coding=utf8

unicode 字符串
在 Python 2.x 中,即使指定了文件使用 UTF-8 的编码格式,但是在遍历字符串时,仍然会 以字节为单位遍历 字符串
要能够 正确的遍历字符串,在定义字符串时,需要 在字符串的引号前,增加一个小写字母 u,告诉解释器这是一个 unicode 字符串(使用 UTF-8 编码格式的字符串)
比如,Python2.x中利用for循环遍历字符串 “我爱你,世界!” 还是会乱码,但是 u"我爱你,世界!" 就不会了

⑨eval函数
eval()函数可以将字符串当成有效的表达式来求值并返回计算结果
str=input(“计算器:”)
print(eval(str))
以上就写成了一个简单的计算器,只不过还有很多bug

千万不要滥用eval
在开发时千万不要使用eval直接转换input的结果
比如eval转换下列代码
import(‘os’).system(‘ls’)
以上代码等价于
import os
os.system(“终端命令”)
执行成功返回0;执行失败,返回错误信息

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章