记住一句话:类是模板,而实例则是根据类建立的对象。html
初学时对类的理解是从类的字面上,能够片面的认为它是一个种类,它是类似特征的抽像,也就是类似的东西,能够把类似特征的事务抽象成一个类。(事务能够是具体的物体或行为)python
以圆为例,圆是具备圆周率(pi)和半径(r)两个类似特征的属性。根据类似特征抽象出圆类,每一个圆的半径能够不一样,那么半径能够做为圆的实例属性;而每一个圆的圆周率pi是相同的,那么圆周率pi就能够做为类属性,这样就定义出了一个圆类。而咱们要知道圆的面积,周长等能够经过类方法计算出来。编程
(看完整篇文章,仍是对类不理解,回过头在来看这部分,对照列子多理解。)数据结构
零散代码(代码块)-->函数(方法)-->类-->模块(文件)
类:表示抽象(模糊)的事物
对象:表示具体(清晰)的事物编程语言
使用 class 语句来建立一个新类,class 以后为类的名称并以冒号结尾:ide
class ClassName: '类的帮助信息' #类文档字符串 class_suite #类体
类的帮助信息能够经过ClassName.doc查看。函数
class_suite 由类成员,方法,数据属性组成。ui
描述人类的文件
类的结构:
一、动态的行为(动词):speak、sing
二、静态的属性(名词):gender、user_name
(1)全局:在类中的任何地方都能使用
(2)局部:只可以在方法内部使用
使用类:
实例化对象:对象名 = 类名 ( 参数【可选的】)翻译
class Human(): """模拟人类""" def __init__(self, sex, name): """初始化属性:gender和user_name""" self.gender = sex self.user_name = name def speak(self): """模拟人类说话""" print(self.user_name.title() + "正在说话。") def sing(self): """模拟人类唱歌""" print(self.user_name.title() + "正在唱歌。")
empCount
变量是一个类变量,它的值将在这个类的全部实例之间共享。你能够在内部类或外部类使用 Employee.empCount
访问。__init__()
方法是一种特殊的方法,被称为类的构造函数或初始化方法,当建立了这个类的实例时就会调用该方法self
表明类的实例,self
在定义类的方法时是必须有的,虽然在调用时没必要传入相应的参数。# 使用类 man = Human('男','xgp') man.speak() lz = Human('男','kk') lz.sing()
class Pet(): def __init__(self,sex,strain): """给属性赋初始值(默认值)""" self.nick_name = '咪咪' self.gender = sex self.stain = strain cat = Pet('公','土猫') # 修改初始值 cat.nick_name = '妙妙' print(cat.nick_name)
妙妙
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称
, 按照惯例它的名称是 self。设计
class Test: def prt(self): print(self) print(self.__class__) t = Test() t.prt()
<__main__.Test instance at 0x10d066878> __main__.Test
从执行结果能够很明显的看出,self 表明的是类的实例,表明当前对象的地址,而 self.__class__
则指向类。
self 不是 python 关键字,咱们把他换成 runoob
也是能够正常执行的:
class Test: def prt(runoob): print(runoob) print(runoob.__class__) t = Test() t.prt()
<__main__.Test instance at 0x10d066878> __main__.Test
实例化类其余编程语言中通常用关键字 new,可是在 Python 中并无这个关键字,类的实例化相似函数调用方式。
如下使用类的名称 Dn
来实例化,并经过 __init__
方法接收参数。
""" 小名和小红各自买了一台笔记本电脑, 其中小名的电脑品牌是联想, CPU8核, 512G固态硬盘,双飞燕鼠标 省红的电脑品牌是机械师, CPU4核, 256G固态硬盘+1T普通硬盘,机械师鼠标 使用面向对象的思惟,编写代码完成以 上描述。 """ class Dn(): def __init__(self,name,brand,cpu,disk,mouse): self.nice_name = name self.nice_pp = brand self.nice_cpu = cpu self.nice_disk = disk self.nice_mouse = mouse def xgp(self): print(self.nice_name + '的电脑配置:“' + '品牌:' + self.nice_pp + ',' + 'cpu:' +self.nice_cpu + ',' + '硬盘:' +self.nice_disk + ',' + '鼠标:' + self.nice_mouse + ',' + '”。') # 可使用点号 . 来访问对象的属性。使用以下类的名称访问类变量 Dn1 = Dn('小名','联想','8核','512固态硬盘','双飞燕') Dn1.xgp() Dn2 = Dn('小米','机械师','4核','256G固态硬盘+1T普通硬盘','机械师鼠标') Dn2.xgp()
小名的电脑配置:“品牌:联想,cpu:8核,固态硬盘:512固态硬盘,鼠标:双飞燕”。 小名的电脑配置:“品牌:机械师,cpu:4核,固态硬盘:256G固态硬盘,机械硬盘1T普通硬盘,鼠标:机械师鼠标”。
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是经过继承机制。
经过继承建立的新类称为子类
或派生类,被继承的类称为基类
、父类
或超类
。
继承语法
class 派生类名(基类名) ...
在python中继承中的一些特色:
若是在继承元组中列了一个以上的类,那么它就被称做"多重继承" 。
派生类的声明,与他们的父类相似,继承的基类列表跟在类名以后,以下所示:
class SubClassName (ParentClass1[, ParentClass2, ...]): ...
class Parent: # 定义父类 parentAttr = 100 def __init__(self): print ("调用父类构造函数") def parentMethod(self): print('调用父类方法') def setAttr(self, attr): Parent.parentAttr = attr def getAttr(self): print ("父类属性 :", Parent.parentAttr) class Child(Parent): # 定义子类 def __init__(self): print ("调用子类构造方法") def childMethod(self): print ('调用子类方法') c = Child() # 实例化子类 c.childMethod() # 调用子类的方法 c.parentMethod() # 调用父类方法 c.setAttr(200) # 再次调用父类的方法 - 设置属性值 c.getAttr() # 再次调用父类的方法 - 获取属性值
调用子类构造方法 调用子类方法 调用父类方法 父类属性 : 200
""" 小名和小红各自买了一台笔记本电脑, 其中小名的电脑品牌是联想, CPU8核, 512G固态硬盘,双飞燕鼠标 省红的电脑品牌是机械师, CPU4核, 256G固态硬盘+1T普通硬盘,机械师鼠标 使用面向对象的思惟,编写代码完成以 上描述。 """ class Dn(): def __init__(self,brand,cpu,disk,mouse): self.nice_pp = brand self.nice_cpu = cpu self.nice_disk = disk self.nice_mouse = mouse # 继承:共享某个类的代码 class XiaoMing(Dn): def __init__(self,brand,cpu,disk,mouse): super().__init__(brand,cpu,disk,mouse) def xgp(self,name): print(name + '的电脑配置:“' + '品牌:' + self.nice_pp + ',' + 'cpu:' +self.nice_cpu + ',' + '固态硬盘:' +self.nice_disk + ',' + '鼠标:' + self.nice_mouse + '”。') class XiaoHong(Dn): def __init__(self,brand,cpu,disk,sim_disk,mouse): self.sim_disk = sim_disk super() . __init__(brand,cpu,disk,mouse) def wsd(self,name): print(name + '的电脑配置:“' + '品牌:' + self.nice_pp + ',' + 'cpu:' + self.nice_cpu + ',' + '固态硬盘:' + self.nice_disk + ',' + '机械硬盘' + self.sim_disk + ',' + '鼠标:' + self.nice_mouse + '”。') xiaoming = XiaoMing('联想','8核','512固态硬盘','双飞燕') xiaoming.xgp('小名') xiaohong = XiaoHong('机械师','4核','256G固态硬盘','1T普通硬盘','机械师鼠标') xiaohong.wsd('小名')
小名的电脑配置:“品牌:联想,cpu:8核,固态硬盘:512固态硬盘,鼠标:双飞燕”。 小名的电脑配置:“品牌:机械师,cpu:4核,固态硬盘:256G固态硬盘,机械硬盘1T普通硬盘,鼠标:机械师鼠标”。
class Empoyee(): """员工类""" def __init__(self,name,years_old,money): """初始化普通员工属性""" self.user_name = name self.user_years_old = years_old self.user_money = money def say_hi(self): """模拟员工自我介绍的方法""" print('我叫'+self.user_name +',工龄' + self.user_years_old +'年,年工资为' + self.user_money +'元。' ) class SE(Empoyee): def __init__(self,name,years_old,money): super().__init__(name,years_old,money) def say_hi(self): """模拟员工自我介绍的方法""" print('我叫'+self.user_name +',工龄' + self.user_years_old +'年,年工资为' + self.user_money +'元。' ) class PM(Empoyee): def __init__(self,name,years_old,money,bonus): super().__init__(name,years_old,money) # 编写子类特有的属性 self.pm_bonus = bonus def say_hi(self): """模拟项目经理自我介绍的方法""" print('我叫'+self.user_name +',工龄' + self.user_years_old +'年,月工资为' + self.user_money +'元,' + '管理奖金' + self.pm_bonus + '元。' ) class CTO(Empoyee): def __init__(self,name,years_old,money,bonus,annual_bonus): super().__init__(name,years_old,money) self.cto_bonus = bonus self.cto_annual_bonus = annual_bonus def say_hi(self): """模拟项目经理自我介绍的方法""" print('我叫'+self.user_name +',工龄' + self.user_years_old +'年,月工资为' + self.user_money +'元,' + '管理奖金' + self.cto_bonus + '元,' + '年终奖' + self.cto_annual_bonus + '元。' ) # 使用类:实例化对象 se = SE('xgp','4','8k') se.say_hi() pm = PM('wsd','6','10000','5000') pm.say_hi() cto = CTO('xgp','10','30000','6000','12000') cto.say_hi()
我叫xgp,工龄4年,年工资为8k元。 我叫wsd,工龄6年,月工资为10000元,管理奖金5000元。 我叫xgp,工龄10年,月工资为30000元,管理奖金6000元,年终奖12000元。
__dict__
: 类的属性(包含一个字典,由类的数据属性组成)__name__
: 类名__module__
: 类定义所在的模块(类的全名是'__main__.className
',若是类位于一个导入模块mymod中,那么className.__module__
等于 mymod)__bases__
: 类的全部父类构成元素(包含了一个由全部父类组成的元组)#!/usr/bin/python # -*- coding: UTF-8 -*- class Employee: '全部员工的基类' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary print "Employee.__doc__:", Employee.__doc__ print "Employee.__name__:", Employee.__name__ print "Employee.__module__:", Employee.__module__ print "Employee.__bases__:", Employee.__bases__ print "Employee.__dict__:", Employee.__dict__
Employee.__doc__: 全部员工的基类 Employee.__name__: Employee Employee.__module__: __main__ Employee.__bases__: () Employee.__dict__: {'__module__': '__main__', 'displayCount': <function displayCount at 0x10a939c80>, 'empCount': 0, 'displayEmployee': <function displayEmployee at 0x10a93caa0>, '__doc__': '\xe6\x89\x80\xe6\x9c\x89\xe5\x91\x98\xe5\xb7\xa5\xe7\x9a\x84\xe5\x9f\xba\xe7\xb1\xbb', '__init__': <function __init__ at 0x10a939578>}
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__
方法运行:
#!/usr/bin/python # -*- coding: UTF-8 -*- class Point: def __init__( self, x=0, y=0): self.x = x self.y = y def __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 销毁
注意:一般你须要在单独的文件中定义一个类
参数的传递图,翻译与pythoncentral网