_init_()函数
所有类都有一个名为__init__()的函数,它在每次使用类创建新对象时都会自动执行,可用于将用户指定的值在初始就赋给对象的属性,或者在创建对象时执行一些固定操作,如下:
class Person:def __init__(self, name, age):self.name = nameself.age = age
以双下划线开头和结尾的函数
这些双下划线函数的名称是预先定义好的,当用户和使用某些内置函数或进行特定操作时,python解释器会自动调用这些双下划线函数。
如, init() 用于初始化对象,str() 用于返回对象的字符串表示,eq() 用于比较对象是否相等。
那么当用户使用print()
函数来打印对象时,python解释器会尝试调用对象的__str__()
函数来获取对象的字符串表示;若没有定义__str__()
函数,就会使用默认的对象表示方式,如下:
class Vector:def __init__(self, a, b):self.a = aself.b = bdef __str__(self):return 'Vector (%d, %d)' % (self.a, self.b)def __add__(self,other):return Vector(self.a + other.a, self.b + other.b)v1 = Vector(2,10)
v2 = Vector(5,-2)
print v1 + v2
输出为:
Vector(7,8)
此外,以双下划线开头的变量表示是私有类型的变量,只能允许这个类本身内部进行访问;以单下划线开头表示protected类型的变量,只允许其本身与子类内部进行访问,不能用于from module import *
self参数
self参数是对类当前实例的引用,用于访问属于该实例的变量。其实self可以改为其他名字,但必须是类中任意函数的首个参数,如下:
class Person:def __init__(mysillyobject, name, age):mysillyobject.name = namemysillyobject.age = agedef myfunc(abc):print("Hello my name is " + abc.name)
类内的函数和普通函数只有一个特别的区别:前者必须有一个额外的第一个参数,按照惯例命名为self。self代表当前对象的地址,而self.__class__则指类
class Test:def prt(self):print(self)print(self.__class__)t = Test()
t.prt()
输出为
<__main__.Test instance at 0x10d066878>
__main__.Test
对象销毁(垃圾回收)
python使用引用计数来跟踪和回收垃圾。在python内部记录着所有使用中的对象各有多少引用。
当对象被创建时,就创建了一个引用计数;当其不再被需要时,即此对象的引用计数变为0时,它被垃圾回收。但回收不是立即的,而是由解释器在适当的时机,将垃圾对象占用的内存空间回收
析构函数__del__()在对象销毁的时候被调用
class Point:def __init__( self, x=0, y=0):self.x = xself.y = ydef __del__(self):class_name = self.__class__.__name__print class_name, "销毁"pt1 = Point()
pt2 = pt1
pt3 = pt1
print id(pt1), id(pt2), id(pt3) # 打印对象的id
del pt1
del pt2
del pt3
输出如下
3083401324 3083401324 3083401324
Point 销毁
类的继承
继承语法如下:
class 子类名(父类名)...
python总是首先查找本类中的方法,若不能在本类中找到对应方法,它才开始到父类中逐个查找。
class Parent: # 定义父类parentAttr = 100def __init__(self):print "调用父类构造函数"def parentMethod(self):print '调用父类方法'def setAttr(self, attr):Parent.parentAttr = attrdef getAttr(self):print "父类属性 :", Parent.parentAttrclass Child(Parent): # 定义子类def __init__(self):print "调用子类构造方法"def childMethod(self):print '调用子类方法'c = Child() # 实例化子类
c.childMethod() # 调用子类的方法
c.parentMethod() # 调用父类方法
c.setAttr(200) # 再次调用父类的方法 - 设置属性值
c.getAttr() # 再次调用父类的方法 - 获取属性值
输出如下:
调用子类构造方法
调用子类方法
调用父类方法
父类属性 : 200
方法重写
若子类想要修改父类中的方法,可以直接在子类中进行重写
class Parent: # 定义父类def myMethod(self):print '调用父类方法'class Child(Parent): # 定义子类def myMethod(self):print '调用子类方法'c = Child() # 子类实例
c.myMethod() # 子类调用重写方法
输出如下:
调用子类方法