第七课.Python面向对象(一)

本文深入解析了面向对象编程中的类(class)和对象(Object)概念,探讨了它们之间的关系,类设计原则,以及Python中的实现细节。通过实例演示了如何创建类、检查对象类型、访问和操作类/实例变量,以及理解类方法、静态方法和私有变量。
摘要由CSDN通过智能技术生成

面向对象编程

在面向对象的编程中,有两个重要概念:类和对象;
类class:同一事物的抽象,像一个描述实例的模板,比如汽车类包含了各种具体的现实中的汽车;
对象Object:某个类的具体实例instance,是看得见摸得着的,比如我家的那辆汽车,在这里注意一下,我个人认为在python中,这个对象应当指实例,python是一切皆对象的,类本质上也是一个对象,实例也是一个对象,但为了更官方地描述,在后面的部分,我依然把实例称作对象
类和对象的关系:假设有这样一个语句a=7,数字7实际上是int类型的一个对象,使用type()就能查看当前对象所属的类,有一句我认为很重要的话,它将在以后的例子里体现出来:类的变量可以供对象共享,对象的变量不能给其他对象共享,正所谓类是共通的,实例之间有所差异;
这里插入一个有意思的哲学问题,有点类似鸡生蛋,还是蛋生鸡:你认为是先有类还是先有实例?我们知道,类是实例的模板,这样来看确实是先有类;但是我们想想人类的思考,我们往往是先看到很多实例,然后才会想着分类,因此,个人觉得应该是先有实例后有对象;
如果有学过OWL语言,其实也会看到面向对象的思想:OWL语言分为schema层和instance层,类似类与对象的思想
下面有一些常用操作,便于我们实际体会类和对象:
1.查看对象所属的类:type([]),type({})
fig1
2.判断对像是否是类的实例:isinstance(6,int),isinstance('python',str)
fig2
3.判断类是否是子类:issubclass()
fig3

类的设计与创建

首先要知道,类有两大成员,一个是变量,一个是方法(即函数),变量又分为类变量和实例变量,方法分为实例方法,类方法,类静态方法;在方法中可能会遇到两个关键字:self和cls,self指向实例,cls指向类本身;下面设计一个学生类进行细致分析:

#学生类的设计
class Student(object):
    #类成员变量
    student_totalnum=0#班级总人数
    student_graduated=0#毕业人数
    student_namelist=[]#班级人员名单
    student_graduated_namelist=[]#班级已毕业人名
    
    #init前后各自两条下划线,代表这是一个魔法函数,是魔法函数中的初始化函数,在创建实例的同时自动调用,self是指向实例本身的对象
    #self.name代表这是实例的变量,__init__则是实例的方法(在类下直接以def定义的函数)
    #叫做实例方法的原因:调用必须依赖实例
    def __init__(self,name,age,gender):
        #实例的成员变量:实例独自拥有
        self.name=name
        self.age=age
        self.gender=gender
        self.examnum=0#学生实例的考试次数
        self.totalscore=0#学生实例的总分数
        
        #类的成员变量:同类实例共享
        Student.student_totalnum=Student.student_totalnum+1
        #注意append返回值为None
        Student.student_namelist.append(name)

class Student(object)代表Student类继承自基类object,直接在类下定义的变量就是类变量,正如之前那句话,类变量是实例共享的,也就是说用这个类创建的实例,它们的类变量及其值将是一样的;
在类中不用任何装饰器定义的函数都是实例函数,必须通过实例才能调用,实例函数必须携带self参数,关于__init__,可能会有些觉得奇怪,看到双下划线,证明这是魔法函数,所谓魔法函数就是一些功能比较奇特的函数,但它仍然是一个实例方法,只不过调用会在创建实例时自动执行,比如我进行实例化:

#将类实例化
baijingyi=Student('baijingyi',20,'male')
hack=Student('hack',20,'male')
#参数默认传递给魔法函数init

在实例方法下的变量都是实例变量,实例变量由self访问,类变量由cls或类名访问;
下面在类中补充一个实例方法:

    #实例方法
    def exam(self,score):
        if score<60:
            return 'fail'
        else:
            self.examnum=self.examnum+1
            self.totalscore=self.totalscore+score
            #若学生examnum>3,则列入毕业名单
            if self.examnum>3 and self.name not in Student.student_graduated_namelist:
                Student.student_graduated_namelist.append(self.name)

通过实例调用实例方法:

#通过实例调用实例方法
baijingyi.exam(99)

fig4
可以看出各个实例的变量是互不干扰的;
如果考试合格次数emamnum超过3次,就可以进入毕业生名单:
fig5

类中的关键字和装饰器

还是重复一次上面说过的,类中有两个重要的关键字self和cls,self指向实例(仅在实例方法参数列表中),cls指向类(仅在类方法参数列表中);
除此之外,还有两个重要装饰器:@classmethod和@staticmethod:
1.如果使用了@classmethod修饰的方法就成为类方法,参数必须包含cls;
2.如果使用了@staticmethod修饰的方法就成为类静态方法,类静态方法的参数列表中一定不能出现self和cls;
实例方法必须用实例调用,类方法和类静态方法既可以用实例调用也可以用类调用;
就在学生类的基础上,我再增加一个类方法用于返回毕业学生名单:

    @classmethod
    def check_graduated(cls):
        return cls.student_graduated_namelist

调用该方法时就可以直接通过类调用,或者还是依旧用实例调用:
fig6
对于类静态方法,参数列表中不能存在cls和self,如果确实需要用到类成员变量,只能使用类名访问:

class PP():
    string='im'

class People():
    string="people"
    #类静态方法
    @staticmethod
    def print_str():
        print("python"+People.string+PP.string)

#调用可以使用类或者实例
People.print_str()

xiaoming=People()
xiaoming.print_str()

观察结果:
fig7

发现了一个问题,目前看来,python的安全性是很低的,只要想访问变量,完全没有阻拦的办法,通过一个类名就访问到了其他类的类成员变量,因此,下面讲一个扩展部分:私有成员变量,说实话,私有成员变量对我而言没多大用处,我使用python主要是用于深度学习,对安全性要求没有这么高
私有成员变量
当在成员变量前加双下划线时,该成员就成为私有成员变量,私有成员变量也有类私有成员变量和实例私有成员变量之分,其访问规则遵循之前说的self,cls,类名访问,与之前不同的是,私有变量只能通过类内部的方法才能访问;
还是那个学生类,我现在加上一个类私有变量和实例私有变量(注意双下划线):
fig8
添加一个实例方法和类方法:
fig9
同样去调用它们,结果是确实可以访问到:
fig10
但现在,当我dir()时,将找不到这两个变量:
fig11
fig12
这说明,私有变量确实隐蔽起来了;
注意到,虽然这么说是私有了,但其实还是可以访问到,只要在类名前加下划线就行:

baijingyi._Student__myscore,Student._Student__clsmyscore
#结果返回:(1000, 999)

Python完全就是全靠自觉,实际上,我只要想添加变量,不管是类变量还是实例变量,直接添加就行:

baijingyi.param='new'#为baijingyi实例添加实例变量
Student.param='new'#为Student类添加类变量
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值