学习笔记九 面向对象编程

时间:2022-06-05 17:26:10

一.面向对象技术简介:

  • 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
  • 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
  • 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
  • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
  • 实例变量:定义在方法中的变量,只作用于当前实例的类。
  • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,素以Dog也是一个Animal。
  • 实例化:创建一个类的实例,类的具体对象。
  • 方法:类中定义的函数。
  • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

二.类:

  三种定义类的方式:

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关键字,方式如下:

del 对象名
 
三.实例方法,类方法,静态方法,属性方法,私有方法:
 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)。

 

四.继承:

  子类可以继承父类的方法而无需重新定义他们。继承最大的好处是子类获得了父类的全部功能。当然,也可以对子类增加一些方法。或者重写父类的方法。

class Lm:
    money = 1000000
    house = 5
    def driver(self):
        print('会开车')

class Mcb(Lm):
    def about_me(self):
        print('我有 %s 钱 ,%s 房子'%(self.money,self.house))
        self.driver()

    def driver(self):#方法重载
        print('会开28个*的汽车')


m = Mcb()
m.driver()
m.about_me()

 

会开28个*的汽车
我有 1000000 钱 ,5 房子
会开28个*的汽车