目录
1.类的基本概念
面向对象的编程,可以将属性和代码集成在一起,定义为类,从而使得程序更加简单、规范和有条理。类中可以定义对象的属性和方法。
(1)对象:面向对象层序设计思想是将一组数据和遮住数据的操作封装在一起,形成一个实体,这个实体被称为对象。
(2)类:具有相同或者相似性质的对象的抽象就是类。对象的抽象是类,类的具体化就是对象。人类是一个类,那么一个具体的人就是一个对象。
(3)封装:定义一个新类的过程就是封装。
(4)继承:如果人类是一个类,那么男人可以定义为人类的子类,男人这个类可以继承父类。
(5)方法:即类的成员函数。
(6)构造函数:一种成员函数,用来在创建对象时初始化对象。构造函数一般与他所属的类完全同名。
(7)析构函数:析构函数与构造函数相反,当对象脱离其作用域时(例如声明的函数已经调用完毕),系统会自动执行析构函数。析构函数往往用来做‘清理善后’工作。
2.定义和使用类
(1)声明类
用class声明一个类。
成员函数必须有一个参数self,且为第一个,这也是成员函数与普通函数得主要区别,self代表对象自身,可以使用self引用类的属性和成员函数。
(2)定义类的对象
即例化对象即可,如Person为类,那么
P = Person(),P即为对象
(3)成员变量
在类中定义的变量,即为成员变量。在类中用到成员变量要通过self.成员变量。
class person:
name = 'jike'
def output(self):
print(self.name)
P = person()
P.output()
python中庸下划线作为变量前缀和后缀用来指定特殊变量:
__x__ 表示系统定义名字;
__x 双下划线的表示的是私有类型的变量,只能是允许这个类本身进行访问,连子类也不可以;
_x 不能用于’from module import *’ 以单下划线开头的表示的是protected类型的变量。即保护类型只能允许其本身与子类进行访问。
python的类中分为公有变量和私有变量,公有变量可以再类的外部访问,用户还可以通过公有变量像类中传递数据。为了保证类的的设计思想和内部结构玩不不对外公开,在类的外部无法访问私有变量。python中除了__x其他都是共有变量。
(4)构造函数
构造函数是一个特殊的成员函数,拥有固定的名称,即__init__()。当创建类的对象实例时系统会自动调用构造函数,通过构造函数对类进行初始化操作。
初始化函数中如果有其他变量(相当于形参),那么在例化中需要加入这些变量(实参)。
class Person:
def __init__(self,name)
self.username = name
def output(self):
print(self.username)
p = Person('jike')
p.output()
(5)析构函数
析构函数同构造函数一样,拥有一个固定的名字,即__del__(),用于释放类所占的资源。
del可以删除一个对象,并释放他所占用的资源。
class mystring:
def __init__(self):
self.str = 'string'
def __del__(self):
print('byebye')
def output(self):
print(self.str)
s = mystring()
s.output()
del s#删除对象
2.类的静态成员
类的静态成员包括静态变量和静态方法。
(1)静态变量
与普通成员变量不同的是,静态变量与普通成员无关,静态变量与对象无关,只属于他们的类。
任何公有变量都可以作为静态变量使用,静态变量可以通过对象或者类访问,但是对象不影响类,而类却影响对象的值。
class mystring:
str1 = 0
def __init__(self):
self.str1 += 1
def __del__(self):
print('byebye')
def output(self):
print(self.str)
mystring.str1 += 1
s = mystring()
s.str1 += 1
print(s.str1)
print(mystring.str1)
#3 首先构造函数自动运行值加1,然后再加1
#1
(2)静态方法
静态方法和静态变量类似,静态方法只属于它的类,而不属于任何一个具体的对象。有如下特点:
首先,静态方法无需传入self,因此静态方法中无法访问实例变量;
然后,静态方法不能直接访问静态变量,但可以通过类名引用静态变量。
因此,静态方法既无法访问实例变量,也不能访问静态变量,所以静态方法与它定义的类没有直接关系,而是起到了类似于函数工具库的作用。可通过对象或者类调用。
class mystring:
var = 'string'
@staticmethod#静态方法
def staticmd():
print('静态方法')
mystring.staticmd()
c = mystring()
c.staticmd()
#静态方法
#静态方法
3.类方法
类方法是python的一个新概念,类方法具有如下特性:
(1)可通过类名调用
(2)无法访问实例变量,但是可以访问类的静态变量(cls.静态变量)
(3)需要传入cls参数
(4)可以通过实例调用
class mystring:
var = 'string'
@classmethod#静态方法
def clsmd(cls):
print(cls.var)
mystring.clsmd()
c = mystring()
c.clsmd()
#string
#string
4.instance
(1)判断某个对象是否属于一个类(instance(对象,类))
(2)返回True或者False
如队列,l = [1,2,3]#这个类已经被定义好
instance(l.list)
#返回True
5.类的继承
类的继承能够避免重复定义。类的继承是成树状的,子类又可以派生更多的子类。。
设计类A,然后派生一个B类,B类可以拥有A所有的属性和函数,这个过程叫作继承。A成为B的父类。
import time
class Users:
username = ''
def __init__(self,uname):
self.username = uname
print('(构造函数:'+self.username+')')
#显示用户名
def dispusername(self):
print(self.username)
class userlogin(Users):
def __init__(self,uname,lastlogintime):
Users.__init__(self,uname)
self.lastlogintime = lastlogintime
def displogintime(self):
print('登录时间:'+self.lastlogintime)
#获取当前时间
now = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
#声明3个对象
myuser_1 = userlogin('admin',now)
myuser_2 = userlogin('lee',now)
myuser_3 = userlogin('zhang',now)
#分别调用父类和子类函数
myuser_1.displogintime()
myuser_1.dispusername()
myuser_2.displogintime()
myuser_2.dispusername()
myuser_3.displogintime()
myuser_3.dispusername()
3(构造函数:admin)
#(构造函数:lee)
#(构造函数:zhang)
#登录时间:2018-06-10 17:10:19
#admin
#登录时间:2018-06-10 17:10:19
#lee
#登录时间:2018-06-10 17:10:19
#zhang
6.抽象类
python可以实现抽象类的概念。抽象类是包含抽象方法的类,而抽象方法不包含任何实现代码,只能在子类中实现抽象函数得代码。抽象方法不包含任何实现的代码,所以通常使用pass。
(1)定义抽象类,通过类库abc实现。
(2)实现抽象类。通过派生子类实现。
(3)多态。
在抽象类中定义一个方法,可在子类中实现,不同子类实现方法不同(有点先占个坑的感觉,类似于TensorFlow中的占位符)。
from abc import ABCMeta,abstractmethod
class Shape(object):
__metaclass__ = ABCMeta
@abstractmethod
def abcmethod(self):
pass
class circle(Shape):
def __init__(self,x,y,r):
self.x = x
self.y = y
self.r = r
def draw(self):
print('Draw Circle:(%d,%d,%d)'%(self.x,self.y,self.r))
class line(Shape):
def __init__(self,x1,y1,x2,y2):
self.x1 = x1
self.y1 = y1
self.x2 = x2
self.y2 = y2
def draw(self):
print('Draw line :(%d,%d,%d,%d)'%(self.x1,self.y1,self.x2,self.y2))
#在不同的子类中,draw有不同的实现方法,这个就是多态
#多态1
c = circle(10,10,5)
c.draw()
#多态2
l = line(10,10,20,20)
l.draw()
#Draw Circle:(10,10,5)
#Draw line :(10,10,20,20)
在不同的子类中,draw有不同的实现方法,这个就是多态
#多态1
c = circle(10,10,5)
c.draw()
#多态2
l = line(10,10,20,20)
l.draw()
#Draw Circle:(10,10,5)
#Draw line :(10,10,20,20)
7.对象序列化
将对象的状态信息转化为存储或传输的形式过程。以后,可以通过读取存储区间,重建该对象。
序列化的过程称为pickle(腌制),重建对象的过程称为unpickle。
(1)将对象序列化为字符串
import pickle
lista = ['c++','C#','python']
listb = pickle.dumps(lista)
print(listb)
listc = pickle.loads(listb)
print(listc)
"""
#b'\x80\x03]q\x00(X\x03\x00\x00\x00c++q\x01X\x02\x00\x00\x00C#q\x02X\x06\x00\x00\x00pythonq\x03e.'
#['c++', 'C#', 'python']"""
(2)将对象序列化到文件
import pickle
lista = ['c++','C#','python']
output = open('data.pkl','wb')
pickle.dump(lista,output)
output.close()
output = open('data.pkl','rb')
listc = pickle.load(output)
output.close()
print(listc)
8.对象赋值
与普通变量一样,可通过赋值操作和传递参数等方式进行复制。
mywcircle = circle(20,20,5)
newcircle = mycircle
newcircle.draw()
#Draw Circle :(20,20,5)
可见两个对象内容完全相同。
9.属性设置
@property
#属性的巧用
#定义一个类
class Student(object):
@property
def score(self):
return self._score
@score.setter
def score(self,value):
if not isinstance(value, int):
raise ValueError('分数必须是整数')
if value < 0 or value > 100:
raise ValueError('分数必须0-100之间')
self._score = value
#相当于把属性设置一个变化范围
>>> s = Student()
>>> s.score = 60 # OK,实际转化为s.set_score(60)
>>> s.score # OK,实际转化为s.get_score()
60
>>> s.score = 9999
Traceback (most recent call last):
ValueError: score must between 0 ~ 100!