博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python面向对象(二)
阅读量:4043 次
发布时间:2019-05-24

本文共 3230 字,大约阅读时间需要 10 分钟。

访问属性及方法

类通过函数(在class语句内由def语句编写的)为实例提供行为。因为这种嵌套的def会在类中对变量名进行赋值,实际效果就是把属性添加到类对象之中,从而可以由所有实例和子类继承。

这种def语句块出现在内内部时,通常就叫方法,而且会自动接收第一个特殊参数(通常为self),这个参数提供了被处理的实例的参照值,并且一定是明确写出来的。
访问对象的属性及方法,需要使用(.)来访问。如果访问类变量,既可以使用类的名称访问,也可以用类的实例名称访问。
如:
创建“Python面向对象(一)”中类的实例,并访问对象中的方法与属性(注意在实例化对象时,不需要再显示写self,会默认带入,表示指向实例本身。)

emp1 = Employee("SR", 10000)emp1.displayCount()emp1.displayEmployee()

执行结果:

total employee  1name : SR , salary : 10000

对类的属性还可以添加、删除、修改,如:

emp1 = Employee("SR", 10000)emp1.displayCount()emp1.displayEmployee()emp1.salary = 20000  #修改属性 salaryprint emp1.salaryemp1.age = 25   #添加属性 ageprint emp1.agedel emp1.age #删除 age属性

执行结果:

total employee  1name : SR , salary : 100002000025

访问属性的其他操作:

1、getattr(obj, name[, default]) : 访问对象的属性。2、hasattr(obj,name) : 检查是否存在一个属性。3、setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。4、delattr(obj, name) : 删除属性。

如:

hasattr(emp1, 'tel') #如果存在tel属性,返回True,否则报异常getattr(emp1, 'tel') #返回tel属性的值setattr(emp1, 'tel', '13111111111') #添加tel属性delattr(emp1, 'tel')#删除tel属性

内置类属性

  • __dict__ : 类的属性(包含一个字典,由类的数据属性组成)
  • __doc__ :类的文档字符串
  • __name__: 类名
  • __module__: 类定义所在的模块(类的全名是’__main__.className’,如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)
  • __bases__ : 类的所有父类构成元素(包含了以个由所有父类组成的元组)

Python的内置类属性的调用,直接使用类名调用,如:print Employee.__doc__。

Python对象销毁(垃圾回收)

同Java语言一样,Python使用了引用计数这一简单技术来追踪内存中的对象。

在Python内部记录着所有使用中的对象各有多少引用。
一个内部跟踪变量,称为一个引用计数器。
当对象被创建时, 就创建了一个引用计数, 当这个对象不再需要时, 也就是说, 这个对象的引用计数变为0 时, 它被垃圾回收。但是回收不是”立即”的, 由解释器在适当的时机,将垃圾对象占用的内存空间回收。

a = 40 # 创建对象 <40> b = a # 增加引用, <40> 的计数 c = [b] # 增加引用. <40> 的计数 del a # 减少引用 <40> 的计数 b = 100 # 减少引用 <40> 的计数 c[0] = -1 # 减少引用 <40> 的计数

垃圾回收机制不仅针对引用计数为0的对象,同样也可以处理循环引用的情况。循环引用指的是,两个对象相互引用,但是没有其他变量引用他们。这种情况下,仅使用引用计数是不够的。Python 的垃圾收集器实际上是一个引用计数器和一个循环垃圾收集器。作为引用计数的补充, 垃圾收集器也会留心被分配的总量很大(及未通过引用计数销毁的那些)的对象。 在这种情况下, 解释器会暂停下来, 试图清理所有未引用的循环。

析构函数__del__ ,__del__在对象消逝的时候被调用,当对象不再被使用时,__del__方法运行:

构造函数解析

构造方法是内置的,用来初始化数据用的,在实例化对象时自动调用。

如果子类没定义自己的构造函数,那实例化该类时,就会自动调用父类的构造方法。所以如果父类构造方法中如果有要实例的变量,实例时就需要传入实参。就算没在子类中调用父类的构造方法,也可以直接用子类的实例调用父类构造方法中的属性。如果在子类中定义了自己的构造方法,就不会自动调用父类的构造方法了,但又想用父类的一些属性,那就必须在子类的构造方法中再调用父类的构造方法,然后传入相应的参数即可。

隐藏数据

Python中经常会看到类中定义的方法名前后有下划线的情况,那这些都表示什么意思呢?

  1. 方法名前后都有两个下划线,表示是Python的内置方法,如__init__()
  2. 方法名只有前面有两个下划线,表示是Python中的隐藏方法,类似于java中的private, 子类与其他类都不能访问,类里面可以任意访问(如__setId())。
  3. 方法名前有一个下划线,表示是Python中的保护方法,类似于java中的protect。子类 可以访问(如_set())。
  4. 方法名前后都没有下划线,表示Python中的公开方法,类似于java中的public。任何都 可访问。
class Person(object):    id = 12   #类静态成员在这儿定义,注意缩进    def  __init__(self,name):        self.name = name        self.__inName = 'ads'    def __setId(self,id1): #隐藏方法        self.id = id1        Person.id = 13

如果像现在这样在外面去调用就会报错:

print p.__setId(14)AttributeError: 'Person' object has no attribute '__setId'

易犯错误总结:

当类的成员变量与成员函数重名时,出现的错误总结。

class Parson(object) :  def __init__(self, name, f1, f2 = 1) :    self.name = name     self.f1 = f1    self.f2 = f2    self.__inName = 'jack'  def f1(self, a) :    print f1, self.a  @staticmethod   def f2(b) :    print b p1 = Parson('joy', 100, 200)#print p1.__dict__, p1p1.f1(2)p1.f2(5)

执行结果出现了报错:

TypeError: 'int' object is not callable

这是因为,在对类实例化时,会自动调用类的构造方法去初始化数据,这样定义的实例变量就会把同名的实例方法给覆盖掉,因为他们都是存在类的一个dict里面,key就是他们的名字,可以使用p1.__dict__查看他们,所以将传进来的int型的成员变量f1和f2当成函数去调用,就会报上面的错误提示。修改时,直接将成员变量和成员函数的名字改成不重名即可。

转载地址:http://tcmdi.baihongyu.com/

你可能感兴趣的文章
Xcode&nbsp;调试加入参数《Apple&nbsp;Dev&nbsp;Do…
查看>>
修改mysql编码《转》
查看>>
Posting&nbsp;images&nbsp;using&nbsp;TWRequest《…
查看>>
mac系统如何显示和隐藏文件&nbsp;《转》
查看>>
iphone开发常用代码(不断更…
查看>>
OpenCV&nbsp;学习笔记
查看>>
UIColor&nbsp;转换为&nbsp;UIImage&nbsp;《转》
查看>>
&lt;iOS4&gt;Switching&nbsp;between&nbsp;front&nbsp;an…
查看>>
opencv&nbsp;pca
查看>>
OpenCV做PCA的一个详尽的介…
查看>>
iOS&nbsp;中用代码写字体,并加入…
查看>>
《转》深入浅出&nbsp;Cocoa&nbsp;多线程编程…
查看>>
多target
查看>>
用&nbsp;HTTP&nbsp;压缩加快&nbsp;Web&nbsp;数据…
查看>>
iOS学习笔记——字符串编码转…
查看>>
GDataXMLNode应用小谈
查看>>
做彩票客户端里涉及支付宝相关收获
查看>>
GData&nbsp;解析Xml以及写xml到文…
查看>>
In&nbsp;App&nbsp;Purchase&nbsp;详细介绍
查看>>
iOS运行回路(RunLoop)总结
查看>>