1.1.面向对象技术简介:
- 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
- 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
- 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
- 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
- 实例变量:定义在方法中的变量,只作用于当前实例的类。
- 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,素以Dog也是一个Animal。
- 实例化:创建一个类的实例,类的具体对象。
- 方法:类中定义的函数。
- 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
1.2.类:
三种定义类的方式:
class My: #经典类 pass class My2(object): #新式类 pass class My3(): #新式类 pass
简单例子:定义一个叫MyDb数据库操作类,里面包含数据库的一些方法。
1 class MyDb: 2 def __init__(self,host,user,password,db,port=3306,charset='utf8'):#构造函数, 3 print('连接数据库') 4 self.conn = pymysql.connect(host=host,user=user,password=password, 5 db=db,port=port,charset=charset) 6 self.cur = self.conn.cursor() 7 8 def execute_one(self,sql): 9 print('返回单条数据') 10 self.cur.execute(sql) 11 res = self.cur.fetchone() 12 return res 13 14 def execute_many(self,sql): 15 print('返回多条数据的') 16 self.cur.execute(sql) 17 res = self.cur.fetchall() 18 return res 19 20 def __del__(self):#析构函数 21 print('关闭数据库连接') 22 self.cur.close() 23 self.conn.close() 24 25 my = MyDb('192.168.1.40','jxz','123456','jxz') #实例化 26 27 #一个变量前面加了self之后,那么在这个类里面的其他的函数都可以用了。 28 29 res = my.execute_one('select * from app_myuser where username="testuser1";') 30 print(res) 31 32 res2 = my.execute_many('select * from app_myuser limit 10;') 33 34 print(res2)
其中__init__和__del__分别是构造函数和析构函数。构造函数是在实例化时候被调用,一般都是为这个实例化对象赋初始值,析构函数是在这个对象生命周期结束的时候调用。他们默认都是自动调用。但是也有显示调用。
__init__()方法是可选的,如果不提供,Python 会给出默认的__init__方法。
__del__()也是可选的,如果不提供,则Python 会在后台提供默认析构函数如果要显式的调用析构函数,可以使用del关键字,方式如下:
1.3.实例方法,类方法,静态方法,属性方法,私有方法:
1 class Car: 2 wheel = 4 #类变量 3 def __init__(self,color,p): 4 self.color = color #实例变量 5 self.p = p 6 7 def help(self): 8 print('汽车有%s个轮子'%self.wheel) 9 print('汽车的颜色是%s'%self.color) 10 print('牌子%s'%self.p) 11 print('='*10) 12 self.haha() 13 self.check_wheel() 14 15 @classmethod 16 def check_wheel(cls):#类方法 17 print('cls的内存地址',id(cls)) 18 print(cls.wheel) 19 cls.haha() 20 21 @classmethod 22 def haha(cls): 23 print('哈哈哈') 24 cls.help2() 25 26 @staticmethod 27 def help2():#静态方法 28 print('这个类的作用是造汽车,它里面有xxx方法') 29 30 @property 31 def yesterday(self):#属性方法 32 import datetime 33 res = datetime.date.today() + datetime.timedelta(-1) 34 return str(res) 35 36 def tom(self): 37 import datetime 38 res = datetime.date.today() + datetime.timedelta(1) 39 return str(res)
实例属性:类里的实例方法的第一个参数必须为self,这是实例方法的唯一标志。可以理解为self就是实例本身,因此实例方法必须在实例化后才可以调用(因为不实例化就是不存在的)。各个实例有自己独立的实例空间,存放自己的实例属性(变量和方法)。所以在实例化后,可以新增实例属性(实例变量)。实例方法里面可以随便通过self来调用实例方法,类方法,静态方法,类变量。
类属性:包括方法和变量,类方法必须由@classmethod装饰,并且方法的第一个参数必须是cls,不需要实例化就可以调用,类属性的空间和实例属性的空间是独立的,一个类的属性空间只有一个,虽然类属性可以被其他对象访问,但是由于空间独立,类属性只能由类自己修改,实例可以访问,无权修改。
1 Car.help2() 2 mcb = Car('赤橙黄绿青蓝紫','马春波') 3 print(mcb.wheel)#实例没有定义wheel的时候,默认使用类变量 4 mcb.wheel=8 5 print(mcb.wheel)#当实例定义了自己的wheel属性的时候,使用的就是自己的wheel 6 print(Car.wheel)
结果:
这个类的作用是造汽车,它里面有xxx方法 4 8 4
要注意的是:实例名.类属性和类名.类属性是两个独立的空间,值互不影响。
静态方法:不需要实例化就可以调用的,它就是一个定义在类里面的普通函数,不能使用实例变量、实例方法、不能使用类变量、类方法。用@staticmethod装饰,没有必写参数。一般用来打印信息。
私有方法:变量、函数,前面加两个下划线就代表是一个私有的,只能在类里面用。在类外面就不能使用,只能通过类方法或者实例方法去修改。出于安全考虑,就是提供了修改或操作的接口才能进行修改,否则其他无权修改。
1 class My: 2 def test(self): 3 self.__password = 123456 4 def say(self): 5 print('password',self.__password) 6 def __set_password(self): 7 self.__password = 7890 8 def update(self): 9 self.__set_password() 10 11 m = My() 12 m.test() 13 m.say() 14 m.update() 15 m.say()
password 123456 password 7890
属性方法:用@property装饰,改方法不允许带参数,例如上述的yesterday(),作用就是在调用的时候省去括号,比如这个方法调用就是print(mcb.yesterday)。
1.4.继承:
子类可以继承父类的方法而无需重新定义他们。继承最大的好处是子类获得了父类的全部功能。当然,也可以对子类增加一些方法。或者重写父类的方法。
class Lm: money = 1000000 house = 5 def driver(self): print('会开车')
def run(self):
print('running...')
return 'abc'
class Mcb(Lm): #子类 def about_me(self): #子类新增一个父类没有的方法 print('我有 %s 钱 ,%s 房子'%(self.money,self.house)) self.driver() def driver(self): #方法重载 print('会开28个轮子的汽车')
def run(self): #方法重载,但保留父类的方法内容
res=super().run() #super的意思就是找到父类
print('fly',res)
m = Mcb() m.driver() m.about_me()