【Python学习】python学习手册--第二十六、二十七章 类代码编写基础和实例

类产生多个实例对象

从底层来看,类几乎就是命名空间。从OOP模型来看,编程中有两种对象:类对象和实例对象。类对象提供默认行为,是实例对象的工厂。实例对象是程序中实际使用的处理对象,虽然可能来自同一个类,但是都有自己各自的命名空间类对象是通过语句定义的,而实例对象是类对象调用产生的,类是产生实例的工厂

类对象提供默认行为

用class语句会创建类对象。

  • class语句会创建一个类对象,并将该对象的引用赋值给变量名(类名),他们都是在导入其所在文件时执行。这一点与def语句类似。
  • class内的赋值语句会创建类的属性。类也是命名空间,该空间中的属性也可以用“点”运算调用。
  • 类属性提供对象的状态和行为。

实例对象是具体的元素

  • 像函数那样调用类对象会创建新的实例对象。
  • 每个实例对象继承类的属性并获得了自己的命名空间。
  • 在类的方法内,对self的属性做赋值运算会产生每个实例自己的属性。在类方法内,self就代表了由该类创建的实例对象。对self属性的赋值就是对实例对象中属性的赋值。
>>> class firstclass:         #定义了一个类
...     def setvalue(self,value):
...         self.testvariable=value
...     def printself(self):
...         print(self.testvariable)
...
>>> test=firstclass()         #构造了一个实例对象
>>> test.printself()          #现在调用打印会报错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in printself
AttributeError: 'firstclass' object has no attribute 'testvariable'
>>> test.setvalue(1234)       #用方法赋值后创建了属性
>>> test.printself()          #正常打印
1234
>>> 

类通过继承进行定制

在Python中,实例从类中继承,而类继承于超类:

  • 超类列在了class头语句中的括号内
  • 类从超类中继承属性。
  • 实例会继承所有可读取类的属性
  • 每个object.attribute都会开启新的独立搜索。python会对每个属性表达式进行类树的独立搜索。
  • 逻辑修改是通过创建子类,而不是修改超类。在子类中重新定义要修改的函数或变量名,就可以由子类对象取代并定制所继承的行为。
>>> class secondclass(firstclass):      #继承firstclass
...   def setvalue(self,value):         #修改了函数
...       self.testvariable2=value 
...   def printself(self):
...       print(self.testvariable2)
... 
>>> test2=secondclass()
>>> test2.setvalue(12345)
>>> test2.testvariable           #函数设置的变量变为testvariable2,函数的作用改变了。
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'secondclass' object has no attribute 'testvariable'
>>> test2.testvariable2
12345
>>> test2.printself()
12345
>>> test.printself()         #完全不应该之前对象的使用,提供代码的复用性
1234
>>> 

Python的类也存在于模块文件中,因此类也是属于模块的属性,模块反应的是一个Python文件,而类只是文件中的语句。按照惯例,Python中的类名应该以一个大写字母开头,以便更好的与模块名区分开来。

类可以截获运算符

通过对类中特定方法名称的定义,可以让python程序响应相应的运算符(运算符重载)。运算符的运算都要经过类的实现来控制。
运算符的重载可以让自己定义的类,像内置对象一样可以用运算符进行特定的运算。运算符重载主要有以下几个概念:

  • 以双下划线命名的方法__X__是特殊的钩子。Python运算符重载是用特殊的方法来拦截相应的运算符,比如当类中出现了__add__方法,就会拦截+运算。Python的运算符与特殊命名方法之间,定义了固定不变的映射关系
  • 当实例出现在运算中时,这类特殊的相应的方法会自动调用。(这有点像响应函数,固定的方法相应特定的运算符。)
  • 类可覆盖(重载)多数内置运算符。有几十种特殊运算符重载的方法的名称,几乎可截获并实现内置类型的所有运算。
  • 运算符覆盖方法没有默认参数,也不需要。如果类中没有定义运算符的重载方法,那么说明该类不支持该运算。
  • 运算符可让类与Python的对象模型相集成。

>>> class thirdclass(secondclass):
...    def __add__(self,other):             #重载了运算符+,让类对象中的变量做运算加法。执行self+other运算
...         return(self.testvariable2+other)
... 
>>> test3=thirdclass()
>>> test3.setvalue(111)
>>> test3+333
444
>>> 

运算符重载的方法是可选的,主要是Python程序员开发工具的人在使用,而不是Python应用程序人员使用,在很多情况下,定义一些方法比重载运算来得更方便与明确。
作为类的设计者,可以选择或者不选择运算符的重载,这取决于有多想让你的类看上去是内置类型。一般来说,只有遇到数据类型为数学对象时,才会有可能使用运算符重载。
特殊参数self和__init__构造函数,是python中OOP的两个基石。
使用print函数打印对象信息时,实际上是调用的对象的__str__方法返回的字符串。

在扩展子类时,可以在定制子类的函数时,调用父类的方法(从逻辑上来说就是在父类的基础上进行修改或增强,提高了代码的可维护性)。

面向对象编程的几个重要概念

  • 实例创建:创建的实例,填充实例的属性,各个实例之间都是独立的命名空间,哪怕是相同类产生的
  • 行为方法:操作实例中的属性是通过类中的行为方法来封装逻辑的。
  • 运算符重载:类中可以对Python中的运算符进行重载,比如打印print对应函数__str__
  • 定制行为:重新定义子类中的方法使其特殊化,在子类中可以调用父类的方法,以达到在父类基础上的定制逻辑,提供代码的复用性,可维护性。
  • 定制构造函数:复用父类的构造函数,定制子类自己的构造函数。

对象持久化

Python程序在运行时,都是在内存中运行。如果推出程序,内存释放后,对象将消失,所以就要使用持久化功能,将对象保存起来。
Python提供三个标准的库模块来实现:
- pickle:任意对象和字节串之间的序列化,对内存中的任意的Python对象,它都能转化成为字节串,并可以导入内存重新使用。
- dbm:实现以键访问的文件系统,可以存储字符串
- shelve:使用另外两个模块,按照键把python系统存储在文件中,综合了以上两个模块,通过键来访问或获取指定的字节串。shelve可以在编程的时候很像字典,但是与它唯一的区别就是,在使用之前要像文件一样打开,并像shelve对象内添加“键(任意的字符串)\值(这里的值可以是任何python对象)”,并在使用完成之后关闭。

import shelve
db = shelve.open("filename")
for object in dict:
    db(object)=dict[object]
db.close()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值