轻量级Python IDE使用(四)——类

1、面向对象编程概述

根据代码组织方式不同,编程语言可以分为以下两种。

  • 面向过程语言:面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现使用的时候再依次调用类似流水线的工作原理。
  • 面向对象语言:面向对象是把构成问题的事务分解成各个对象,依靠各个对象之间的交互推动程序执行,进而实现问题的解决。

面向对象特征:封装、继承、多态

2、类和对象

2.1、类的创建

使用class创建类,模板如下:

class ClassName(bases):
    class_suite

class是关键字,bases是要继承的父类,默认继承object类。
class _suite是类体,主要包含属性和方法。
类、属性和方法的命名约定惯例如下:

  • 类名表示实例的抽象,命名时首字母大写
  • 属性使用名词作为名字。如name、age
  • 方法名一般指对属性的操作,其命名规则一般采用动词加名词属性名称形式,如updateName,updateAge

例:

class People:
    name = "王李"

    def update_name(self, name):
        self.name = name

python的类分为两种

1.经典类
python2.x中类的定义的默认方式,不继承object类,其内部有属性和方法组成。经典类定义的典型方式如下:

class A:
    pass

2.新式类
python3.x中类的定义的默认方式,必须继承object方法,其典型定义方式如下:

class A(object):
    pass

新式类修复了经典类的一些bug(如多继承时的歧义等),并且提供了对类方法和静态方法的支持。
在python3.x中,如果没有显示指明要继承的父类,则默认继承object类。

class A:
    pass

class A():
    pass

class A(object):
    pass

在python3.x中,无需继承,例子中的三种创建效果一样。自动继承object类。

新式类添加了一些内置属性和方法,如下所示:

__name__:属性的名字
__doc__:属性的文档字符串
__get__(object):获取对象属性值的方法
__set__(object, value):设置对象属性值的方法
__delete__(object, value):删除对象属性值的方法

2.2、对象的创建

类创建完之后,就应该创建该类的实例或对象了,该过程称之为实例化。当一个对象被创建后,就包含标识、属性和方法这三个方面的对象特征了。其中,对象标识用于区分不同的对象,属性和方法于类中的常用变量和成员函数相对应
声明一个类

class People:
    def __init__(self,name,age,wight):
        self.name = name
        self.age = age
        self.wight = wight

创建一个lisi对象

lisi = People("李四",20,'50kg')
print(lisi.name,lisi.age,lisi.wight)

2.3、类的属性

属性分为类级别和实例级别两种。实例级别的属性值默认共享类级别的属性值。除非显式进行赋值操作。例:

class A():
    age = 10

obj1 = A()
obj2 = A()

如上所示,存在三个实例,分别是类实例A和对象实例obj1、obj2。
obj1和obj2这两个对象实例共享类实例A的属性age:

print(obj1.age,obj2.age,A.age)#10 10 10

显式修改obj1的属性

obj1.age += 2
print(obj1.age,obj2.age,A.age)#12 10 10

修改类实例A的属性

A.age += 3
print(obj1.age,obj2.age,A.age)#12 13 13

修改了对象实例obj1的属性值age,其属性值和类实例A的属性值已经独立。而对象实例obj2的属性值从来没有修改过,所以它还是和类实例A的属性值保持一致。

python对于属性的设置采用“类.属性 = 值”或"实例.属性 = 值"的形式。如 obj1.age += 2 等价于 obj1.age =obj1.age + 2,该语句包含了属性获取及属性设置两个操作。

python语言中的属性操作遵循三个规则:

  • 属性的获取是按照从下到上的顺序来查找属性
  • 类和实例时是两个完全独立的对象
  • 属性设置是针对实例本身进行的

类的定义由属性和方法组成,属性是对数据的封装,方法则是对类行为的封装。属性按使用规范分为公有属性和私有属性,使用范围取决于属性名称。类的属性如下所示。

类的属性

属性类别 介绍 备注
公有属性 类中和类外调用的属性。 若无特别说明。变量默认为公有属性。
私有属性 不能被类以外的函数调用的属性。 命名以双下划线“__”开始的成员变量就是私有属性,可以通过instance.__ClassName__atttibute方式访问 。
内置属性 由系统在定义类的时候默认添加的。 命名一般由前后各两个下划线“__”组成,如__doc__等。

内置属性

属性名 作用
__name__ 类的名字
__doc__ 类的文档字符
__bases__ 所有父类构成的元组
__dict__ 类的属性
__module__ 类定义所在的模块
__class_\ 实例对应的类

内置实例属性

属性名 作用
__class_\ 实例对像所属的类名
__dict__ 实例对像的属性

2.4、类的方法

类方法也包括公有方法、私有方法、类方法和静态方法。

类的方法

方法类别 介绍 备注
公有属性 不能被类直接调用,需要使用实例化对象调用。 若无特别说明。变量默认为公有属性。
私有方法 不能被外部的类和方法调用,其定义和私有属性的定义相同 需要在方法前面加上双下划线__
类方法 能被类所调用,也能被方法调用 被classmethod函数调用或被@classmethod装饰器修饰的方法
静态方法 相当于“全局方法” ,可以被类直接调用,也可以被所有实例化对象共享。 该方法通过调用staticmethod方法或被@staticmethod装饰器来声明,不需要"self"语句。

例:

class People:
    def Play(self):
        print("公有方法play")
        self.__Study()
        
    def __Study(self):
        print("私有方法study")

    def Breath(self):
        print("类方法1 Breath")
    Breath1=classmethod(Breath)

    def Cry():
        print("静态方法1 Cry")
    Cry1 = staticmethod(Cry)
        
    @classmethod
    def Breath2(self):
        print("类方法2 Breath")

    @staticmethod
    def Cry2():
        print("静态方法2 Cry")

people = People()
people.Play()#People.Play()会报错
#people.__Study() 会报错
#People.__Study() 会报错
people.Breath()#People.Breath()会报错
people.Breath1()
People.Breath1()
people.Breath2()
People.Breath2()
People.Cry()# people.Cry()会报错
people.Cry1()
People.Cry1()
people.Cry2()
People.Cry2()

类方法于静态方法的区别

  • 静态方法不能使用self的方式调用
  • 静态方法调用时会预先将类中用到的属性和方法进行加载,而类方法则是随时调用。因此,类方法相比静态方法具有不占资源的优势,但是速度不及静态方法。
  • 静态方法调用类中的属性是需要使用“类名.属性”的格式

2.5、内部类

类的内部定义的类,主要目的是为了更好抽象世界。

class People:
    code = 0

    class Father:
        code = 1

    class Mother:
        code = 2

zhangsan = People()

lisi = zhangsan.Father()#第一种实例化
print(lisi.code)#1
limi = zhangsan.Mother()#第二种实例化
print(limi.code)#2

2.6、魔术方法

在python语言中,所有以双下划线__包起来的方法,都统称为“魔术方法”。这些方法在实例化时会自动调用,比如__str__()、__init__()、__del__()等,使用魔术方法可以将复杂逻辑封装成简单API。

魔术方法的__init__()方法一般叫做构造函数,用于初始化类的内部构造和参数。如果不提供,Python语言会给出一个默认的__init__()方法

魔术方法的__del__()方法函数叫做析构函数,用于释放对象占用的资源。__del__()函数是可选的。如果不提供,Python语言会在后台提供默认析构函数。

魔术方法中,有些可以实现属性访问控制的功能,如__getattr__(self, name),__setattr__(self, name,value)方法等。

class People:
    name = "人"

    def __init__(self, n="非洲人"):
        self.name = n
        print("我是构造函数",self.name)

    def __del__(self):
        print("我是析构函数",self.name)

p = People()
ou = People("欧美人")
p.__del__()
print(p)

del p
del ou
#print(p) #no define error
#print(ou)#no define error

运行结果

我是构造函数 非洲人
我是构造函数 欧美人
我是析构函数 非洲人
<__main__.People object at 0x0000011A2B8DE9B0>
我是析构函数 非洲人
我是析构函数 欧美人

对于这些魔术方法,在创建对象时可以自动执行。当对象字典执行析构函数p.del()后,对象仍然存在,但是在调用del p后,对象就已经被回收删除,无法再次使用。

3、类间关系

3.1、依赖关系

用实例方法执行某个功能时,如果需要使用另一个类的实例的方法来完成。则称这两个类存在依赖关系。

class Person:
    def play(self, tools):
        tools.run()
        print("开始玩游戏")

class Computer:
    def run(self):
        print("打开电脑")

class Phone:
    def run(self):
        print("打开手机")

c = Computer()
p = Phone()
person = Person()
person.play(c)
person.play(p)

运行结果:

打开电脑
开始玩游戏
打开手机
开始玩游戏

3.2、关联关系

一个类的属性类型是另一个类的类型,则称这两个类之间存在关联关系。根据单值、多值由分为一对一关联、一对多关联。
一对一关联

class Boy:
    def __init__(self, name, grilFriend=None):
        self.grilFriend = grilFriend

    def play(self):
        if self.grilFriend:
            print(f"带女朋友{
      
      self.grilFriend.name}去玩")
        else:
            print("单身快乐")

class Girl:
    def __init__(self, name):
        self.name = name

g = Girl("小红")
b = Boy("小刘",g)
b.play()

b = Boy("小刘")
b.play()

运行结果

带女朋友小红去玩
单身快乐

一对多关联

class School:
    def __init__(self, name):
        self.teach_list = []
        self.name = name

    def recruit(self, teach):
        self.teach_list.append(teach)

    def attend_class(self):
        for t in self.teach_list:
            t.work()

class Teacher:
    def __init__(self,name):
        self.name = name

    def work(self):
        print(f"{
      
      self.name}在上课")

xph = School("小屁孩")
t1 = Teacher("太白")
t2 = Teacher("观音")
t3 = Teacher("扫地僧")

xph.recruit(t1)
xph.recruit(t2)
xph.recruit(t3)
xph.attend_class()

运行结果

================== RESTART: D:/Python/Project/Study/class9.py ==================
太白在上课
观音在上课
扫地僧在上课

3.3、继承关系

继承类是在已有类基础上构建新类的机制,该新键类也成为子类。子类可以增加新的属性或功能也可以继承父类的功能。通过继承可以复用以前的代码,大大提高开发效率。

class People:
    place = "地球"
    def __init__(self):
        print("我是构造函数")
    
    def Study(self):
        print("我爱机器学习")

class Japan(People):
    place = "日本"
    def __init__(self):
        print("子类构造函数 日本省")

    def Study(self):
        print("日本省的人学习")

class China(People):
    place = "中国"
    def __init__(self):
        print("子类构造函数 中国")
        People.__init__(self)
   
    def Study(self):
        print("中国人学习")

class Ren(China, Japan):
    pass

Uchan = Japan()
zhangheng = China()
Lini = Ren()
print(Uchan.place)
print(zhangheng.place)
print(Lini.place)
Uchan.Study()
zhangheng.Study()
Lini.Study()

运行结果:

================== RESTART: D:/Python/Project/Study/class10.py =================
子类构造函数 日本省
子类构造函数 中国
我是构造函数
子类构造函数 中国
我是构造函数
日本
中国
中国
日本省的人学习
中国人学习
中国人学习

猜你喜欢

转载自blog.csdn.net/weixin_45724919/article/details/135180597