您的位置:首页 > 编程语言 > Python开发

Python面向对象(二)

2015-09-29 20:36 489 查看

访问属性及方法

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

这种def语句块出现在内内部时,通常就叫方法,而且会自动接收第一个特殊参数(通常为self),这个参数提供了被处理的实例的参照值,并且一定是明确写出来的。

访问对象的属性及方法,需要使用(.)来访问。如果访问类变量,既可以使用类的名称访问,也可以用类的实例名称访问。

如:

创建“Python面向对象(一)”中类的实例,并访问对象中的方法与属性(注意在实例化对象时,不需要再显示写self,会默认带入,表示指向实例本身。)

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


执行结果:

total employee  1
name : SR , salary : 10000


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

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


执行结果:

total employee  1
name : SR , salary : 1000020000
25


访问属性的其他操作:

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中经常会看到类中定义的方法名前后有下划线的情况,那这些都表示什么意思呢?

方法名前后都有两个下划线,表示是Python的内置方法,如__init__()

方法名只有前面有两个下划线,表示是Python中的隐藏方法,类似于java中的private, 子类与其他类都不能访问,类里面可以任意访问(如__setId())。

方法名前有一个下划线,表示是Python中的保护方法,类似于java中的protect。子类 可以访问(如_set())。

方法名前后都没有下划线,表示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__, p1
p1.f1(2)
p1.f2(5)


执行结果出现了报错:

TypeError: 'int' object is not callable


这是因为,在对类实例化时,会自动调用类的构造方法去初始化数据,这样定义的实例变量就会把同名的实例方法给覆盖掉,因为他们都是存在类的一个dict里面,key就是他们的名字,可以使用p1.__dict__查看他们,所以将传进来的int型的成员变量f1和f2当成函数去调用,就会报上面的错误提示。修改时,直接将成员变量和成员函数的名字改成不重名即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: