12.1面向对象

12.1.1什么是类?

  • 假设:有50双鞋,怎么去管理这50双鞋

进行分类:

10双运动鞋

10双皮鞋

10双凉鞋

10双拖鞋

10双童鞋

 

我会把每种鞋做一个分类,然后放到一个鞋柜里面。

class本质:分类管理

 

12.1.2面向对象编程:用类的方式来管理你的数据

 

Ø  图书:

历史:清朝、近代史、现代史……

计算机

文学

 

类:(相关数据存在一起,并且有一组操作相关数据的方法)

成员变量:属性

方法:操作成员变量(属性)类里面写的函数叫做方法。

 

Ø  游戏设计场景:

玩过游戏。主人公,进入一个场景,有10个小怪物

是一样的。有攻击力,血(100格)。如果小怪物有多个值需要管理,小怪物的血量、小怪物出现在屏幕的位置;

例如:

{“blood“:100,”location”:”10,10”}

[[100,(10,10)]]

 

假设小怪物有10个属性,那么我写10个字典,那么我写的10个字段,有100个值要管理

 

10个小怪物。记住10个小怪物所有的变量在哪里,怎么操作?

 

写一些函数,来操作这些数据。

函数你实现的时候,你觉得需要实现哪些功能?

 

10个方法:所有操作的数据方法

add_blood():

blood+=1

minus_blood():

blood-=1

 

move():

x-=10

y-=10

 

这些都是使用“类“来实现的

 

示例:

class soldier():

    """小怪物的类"""

    def __init__(self,blood,location_x,location_y):    #小怪物的属性

        self.blood = blood                                   #血量

        self.location_x = location_x                       #x轴坐标

        self.location_y = location_y                      #y轴坐标

 

    def add_blood(self,num):                                #小怪物加血的方法

        if self.blood<=100:                                 

            self.blood+=num

            if self.blood>100:

                self.blood = 100

 

    def miuns_blood(self,num):                             #小怪物的掉血方法

        if self.blood>=0:

            self.blood-=num

            if self.blood<0:

                self.blood = 0

    def tell_blood(self):

        return self.blood

 

s1 = soldier(100,10,10)       #实例化,用模板做出来的东西(相当于模具)

s2 = soldier(90,10,20)

s3 = soldier(80,10,30)

 

print(s1.tell_blood())

print(s2.tell_blood())

print(s3.tell_blood())

 

类:(相关数据存在一起,并且有一组操作相关数据的方法)

  • 成员变量:属性(数据)
  • 方法:操作成员变量(属性)类里面写的函数叫做方法。

 

类比说明:

生产杯子,杯子的模具(类),可以设定不同的参数来生产杯子。

设定好不同的参数(通过构造函数传参)

 

类:soldier

实例化:传入不同的参数(调用构造函数),关键字__init__构造函数

s1    传入的都是__init__构造的函数

s2

s3

 

 

Ø  圆的面积和周长:

self.xxx实例变量

def __init__(self,blood,location_x,location_y):

        self.blood = blood

在类里面定义的函数叫做方法

 

import math

class circle(object):

 

    def __init__(self,radius):              变量一个值,radius

        self.radius = radius

   

    def get_area(self):                     

        return math.pi*self.radius*self.radius

 

    def get_perimeter(self):

        return 2*math.pi*self.radius

 

for i in range(1,6):

    print(a)

    print(a.get_area())

print(a.get_perimeter())

 

Ø  如果传入了一个负数,那么从数学角度来讲是非法的。

def add():#函数

    return a+b

 

c = [1,3.14,6.28]

c[0]=-1

半径不允许设定为负数。

 

用类来限制修改半径为负数

 

示例:

import math

class circle(object):

 

    def __init__(self,radius):

        if radius<=0:                                    #保障了数据的安全性

            self.radius = 1

        else:

            self.radius = radius

            

 

    def set_radius(self,radius):                        #只有调用这个方法下面的逻辑才会生效

        if radius<0:

            self.radius = abs(radius)             #abs为函数,返回radius绝对值

        elif radius == 0:

            self.radius = 1

 

    def get_area(self):

        return math.pi*self.radius*self.radius

 

    def get_perimeter(self):

        return 2*math.pi*self.radius

 

c=circle(-1)

print(c.get_area())

c.set_radius(-2)                   #通过abs把-2转换成2

print(c.get_area())

 

类:

封装了数据,和操作数据的规则,保证数据的安全。

保存数据、修改数据、计算了只会输出数据,通过类的方式可以避免每一个步骤出现脏数据(不是唯一的,但是是一个比较好的方案)

总结:

1 生成实例的时候很方便,快速的把多个数据封装到类里面

2 操作数据的规则写在方法里面,然后修改任意的数据都需要去操作这个方法,保证这个数据不会改成脏数据

 

Ø  两件事情都需要做数据安全设定

1 实例化的时候

    def __init__(self,radius):

        if radius<=0:

            self.radius = 1

        else:

            self.radius = radius

2 修改数据的时候

    def set_radius(self,radius):

        if radius<0:

            self.radius = abs(radius)

        elif radius == 0:

            self.radius = 1

 

函数和类的区别
函数:数据可以被改变

a=[1,2,3,4]  #只存正数的列表

def set(a,index,new_value):

    if new_value >= 0:       #通过if制定取值规则

        a[index] = new_value   #a[index],index在里面属于位置,传入的时候也只是代表位置信息,new_value代表传进来的值,通过a[index] = new_value这种方式对原列表a[位置]进行修改值

    return a[index]

 

set(a,0,100)

print(a)

set(a,0,-50)          #不会修改

print(a)                 #只会返回上一个正确变量100

 

a[0]=-50              #但是不能保证所有人都按照上面的规则,直接越过set类

print(a)                 #成功修改-50

                          返回[-50, 2, 3, 4]

类:数据安全

class positive_num_list(object):

  

    def __init__(self,a):

        self.__value = a

   

    def set(self,index,value):

        if value<0:

            return

        self.__value[index] = value

 

    def get(self):

        return self.__value

 

p= positive_num_list([1,2,3,4])

#p.set(0,100)

#print(p.get())

#p.set(0,-100)

#print(p.get())

p.__value[0] = -100     #__value[0]属于class类中的私有变量,这种方法不可以传参、修改

                                   ,私有变量外面是不能访问的

Traceback (most recent call last):

  File "b.py", line 19, in <module>

    p.__value[0] = -100

AttributeError: 'positive_num_list' object has no attribute '__value'

python内置函数和自定义函数是否冲突:

  • 代码内容:

class positive_num_list(object):

  

    def __init__(self,a):

        self.__value = a

   

    def set(self,index,value):

        if value<0:

            return

        self.__value[index] = value

 

    def get(self):

        return self.__value

 

p= positive_num_list([1,2,3,4])

 

 

p.set(1,50)                   #p.set就等于类的命名空间,set只能在p.下面使用

print(p.get())

 

print(set([1,1,2,2]))       #这set可以在全局使用

 

  • 返回数据:

D:\>py -3 b.py

[1, 50, 3, 4]

{1, 2}

 

总结:这两者之间没有任何影响

 

类的解释:

class p():

    pass

 

p=p()

print(p)

 

D:\>py -3 b.py

<__main__.p object at 0x0000015F47A25C18>

 

_main__:表示当前程序

.p:表示对象

Object:表示p类下面的实例

at 0x0000015F47A25C18:在某个内存的地址

 

value和self.value的解释:

class p():

    def __init__(self,value): #构造方法,初始化的

        self.__value = value    #value局部变量,

                                            #self.value叫做实例变量,加入__ value便为了私有变量,

外面不能访问;

 

p=p(10)

print(p.value)

 

通过制定方法规则实现外部访问修改__ value

class p():

    def __init__(self,value):                #实际场景中不需要传参数可以不写

        self.__value = value

   

    def get(self):         #制定实例访问方法

        return "***: " + str(self.__value )  #访问规则

 

    def set(self,value): #制定实例修改方法

        if isinstance(value,(int,float)):      #修改规则

            self.__value = value

        return None

                                           

p=p(10)         给类变量

print(p.get())

p.set("a")       #修改规则不符,无法修改

print(p.get())

p.set(-5)        #符合规则访问set方法进行修改变量

print(p.get())

 

self的作用:

 

class p():

    def __init__(self,value):

        self.__value = value

   

    def get(self):         #self传递位置

        return "***: " + str(self.__value ) 

 

    def set(self,value):

        if isinstance(value,(int,float)):

            self.__value = value

        return None

                                           

p1 =p(1)

p2 =p(2)

p3 =p(3)

 

print(p1)

print(p2)

print(p3)

D:\>py -3 b.py

<__main__.p object at 0x0000028FC6BF45F8>

<__main__.p object at 0x0000028FC6BF4630>

<__main__.p object at 0x0000028FC6BF4668>

内存存中的位置:A

P:变量

类定义的方法

 

类中所有定义的方法,类变量,只有一份

实例在中内存中:有0个,1个活多个。

 

内存中的位置:b

p1的实例:self:__value=1

 

内存中的位置:c

p2的实例:self:__value=2

 

内存中的位置:d

p3的实例:self:__value=3

 

self的使用情况:

p1.get()--->调用的时候会把位置b发送给类定义的方法

self:是一个方法参数,内存位置b

get方法从内存b的位置找到,__value值,然后执行方法中的代码。

 

self传递的是某个实例的地址。实例地址里面的所有变量都可以在方法中进行使用。

 

print(p1)

print(p2)

print(p3)

p3.set(1,2)  #p3的地址传递给了(self,1) -->value,2是多余的。。

 

对应的错误信息:

TypeError: set() takes 2 positional arguments but 3 were given

 

类总结:

1)把数据封装到实例里面,同统一的规则来进行存取,保证了数据的安全和一致性。

2)方便进行扩展

 

变量前面加self.的叫做实例变量

如果不加self.的叫局部变量

 

class p():

    def __init__(self,value): #构造方法,初始化的

        self.value1 = value   #局部变量不能跨方法访问

                     #value和value局部变量,不能跨方法访问

        print("构造函数:%s"%self.value1)

                         #self.value叫做实例变量

 

    def get(self):         #实例方法

        return self.value1

 

                                           

p1 =p(1)

print(p1.get()) #局部变量不能跨方法访问

类:

  1可以封装数据,制定数据的存储规则,保证数据的安全

  2 类相当于模板,可以通过构造函数做初始化,快速生成实例

  3 基于类,可以进行扩展。设计模式:“”“通过”面向对象”的方式设计很多种程序上数据访问的技巧”“”

4 实例方法内存中存储的类变量和方法,只有一份。每个类的实例,都在内存中有一个地址(实例可以有0个,1个或多个)

5 类中定义的实例方法(方法中有self参数),可以操作每个实例中封装的变量

6 实例变量(self.开头的)可以在不同的实例方法中被访问。

  每个实例变量都存在对应的实例所在的内存地址中。

7 __变量是私有变量,除了类中的实例方法访问,外部不可以直接访问和修改

posted on 2021-11-15 21:23  Wgl123  阅读(26)  评论(0编辑  收藏  举报