Python 对于面向对象编程的初步总结(一)

 个人觉得以具体案例说明功能会更好一些。下面,以校园学生信息为背景做的相关总结。

初步概述:

之前我们讲到面向对象是一个个具体的类,比如人类、动物等。而实例就是一个个实例化的类值,比如张三、李四、小狗、小猫等,而张三年龄是多少,性别男的女的是指定的属性值,那张三会不会赚钱呢,会不会讨女孩子喜欢是给指定的方法值。

那下面回到背景分析,首先当社会人类(Human)要进入学校的时候,应当收集这个人类的一些信息,当信息收集完毕将赋予学生(Student)这个类;

(在这里面会有一个知识点,就是有学生类别的肯定有个人类类别,但是不是所有的人类都有学生类别,这里面有一个继承概念)。当我们以学生身份进入校园的时候,我们开始寻找我们的教室、找我们亲爱的辅导员报道、办理校园电子卡、再认识我们的我们的宿舍等,这些是我们学生的特定属性。

等我们把学生入学安排好之后,就要开始学习了,学习的话我们得知道我们学习哪些课程,对应课程分数、对应考核等级等学科(Subject)类。

而我们这个人(People)又是人类、学生、学科等相关类别,拥有对应属性。

接下来我们进行代码构造:

一、初步建设框架:

class Human(object):
    pass

class Student(Human):
    pass

class Subject(object):
    pass

class People(Human,Student,Subject):
    pass

在这里面我们可以看到Student类为Human类的子类【继承】,而People类是其余三者的子类【多重继承】

二、内容优化:

我们已经有最简单的框架了,那接下面我们就应该具体化对应属性、判别对应逻辑等了。首先定义人类必须有哪些对应的属性呢,用这些对应属性我们可以来区分一个个的人,比如这里面有姓名(name)、年龄(age)、性别(sex)、身份证号码(card)、手机号码(phone)、家庭住址(address)等属性;那对于Student来说哪些是应该有的属性呢,比如这里面有年级别(grade)、专业(major)、班级(banji)、辅导员(instructor);那对应Subject来说应该有哪些属性呢,比如这应该有语文(yuwen)、数学(math)、英语(yingyu)等课,那调整代码如下:

class Human(object):
    def __init__(self,name,age,sex,card,phone,address):
        self.name = name
        self.age  = age
        self.sex = sex
        self.card = card
        self.phone  = phone
        self.address = address

class Student(Human):
     def __init__(self,grade,major,banji,instructor):
        self.grade = grade
        self.major  = major
        self.banji = banji
        self.instructor = instructor

class Subject(object):
    def __init__(self,yuwen,math,yingyu):
        self.yuwen = yuwen
        self.math  = math
        self.yingyu = yingyu

class People(Human,Student,Subject):
    pass


在这里面我们已经初步定义了各个类别的属性值,下面我们创建试试这些属性值试试。下面我们创建一个人类Oliver,但是创建实例的时候发现报错,提示缺失这六个属性值。查找了解到在___init__为初始化属性,就是创建的实例必须含有字这些属性,创建的属性可以在创建的过程中赋值,也可以是类初始化定义值。下面我们填写上对应值就不会报错了。创建如下,发现则是创建成功了,但是提供了一长长信息发现,查找到这是对应的内存地址。那下面我们就让打印出来查看信息方便直观点。增加函数如下:

def __str__(self):
        return "各个信息如下:name: {0}, age: {1}, sex: {2}, card: {3}, phone: {4}, address: {5}".format(self.name,self.age,self.sex,self.card,self.phone,self.address)

__repr__ = __str__

增加完之后我们再试试查看下,需要的信息都直接展现出来了。我们创建了一个Oliver实例,在这里我们尝试修改里面的属性值试试看。我们发现,里面属性被修改了,我们都知道Python是面向对象语言是个动态语言,如果我们没有做任何限制的话,在类里面我们可以任意添加、修改、删除属性值(想想好可怕,我都变成千年老妖了)。为了防止我们的数据被任意调整,我们需要限制我们的属性,代码如下:

class Human(object):
    def __init__(self,name,age,sex,card,phone,address):
        self.__name = name
        self.__age  = age
        self.__sex = sex
        self.__card = card
        self.__phone  = phone
        self.__address = address

下面我们尝试一下再次调用年龄,我们会发现说没有找到这个name属性,这样外部就无法调用了。那我们继续用赋值试试。在这我们发现我们name属性可以赋值成功,可是对应的打印信息出来是没有信息调整的,原来是程序对实例创建了一个Oliver.name的新属性,我们查看Oliver.name试试看。《还是有些疑问》现在我们的属性不会被外部调用了,但是对于生产环境来说这些实例的属性肯定是存在调整的,那以我们调整name信息为例,代码调整如下:

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self,value):
        self.__name == value

    @name.deleter
    def name(self):
        del self.__name

在这里面用的装饰器定义,初步感觉应该用的这个。在这里面我们定义的name属性查看,name的setter值修改,name属性的删除deleter,下面我们来尝试修改一下。这样我们又可以调整里面的内部属性了。看一下对比图

那么就有这样的疑问了,这里面我们输入什么类型其实都可以输出,比如我的name叫[1,2,3,4,5]其实也是可以的,测试结果在这里面应该输入的是str字符串。所以在这里面我们还要加上输入类型的判断。代码如下:

@name.setter
    def name(self,value):
        if isinstance(value,str):
            self.__name = value
        else:
            raise ValueError('Is not string type!')

我们在修改named的地方做了判断语句,当类型正常的时候我们返回值,不正确的时候我们报错误信息。测试如下:

那现在我们可以正常的修改我们的属性了,并且也可以获得想要的类型。

在这就又产生一个问题,我们修改一个属性值创建装饰器单独修改,那如果我有十个,百个属性需要修改,也是要创建一百份对应修改嘛,那岂不是有很多的工作量,必然有一些是重复的。是否有方法可以把能合并的合并处理呢。暂时没有想到办法,待后续继续研究查询,初步想法是创建一个子类,这个子类相当于修改类,修改父类的属性值,因为属性值有类型区分,做对应的条件判断再输出。构想的代码框架为:

class Human():
    def call_adjustment(self):
        child_method = getattr(self, 'out')# 获取子类的out()方法
        
class adjustment(Human):
    def out(self,attribute,value):
        if isinstance(attribute,str):     #之前定义的属性类型只有字符串与整形两种,这都是字符串的类型
            if isinstance(value,str):     #如果调整的值也是字符串
                self.attribute = value
            else:
                raise ValueError('Is not string type!')
        else:                             #反之就是整形了
            pass

我们程序做了优化,到现在为止的代码信息如下:

class Human(object):
    def __init__(self,name,age,sex,card,phone,address):
        self.__name = name
        self.__age  = age
        self.__sex = sex
        self.__card = card
        self.__phone  = phone
        self.__address = address

    def __str__(self):
        return "各个属性内容如下:name: {0}, age: {1}, sex: {2}, card: {3}, phone: {4}, address: {5}".format(self.__name,self.__age,self.__sex,self.__card,self.__phone,self.__address)
    __repr__ = __str__

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self,value):
        if isinstance(value,str):
            self.__name = value
        else:
            raise ValueError('Is not string type!')

    @name.deleter
    def name(self):
        del self.__name

    def call_adjustment(self):
        child_method = getattr(self, 'out')  # 获取子类的out()方法

Oliver = Human("Oliver",25,"男",1818181818181818,12345678911,"北京")

class Student(Human):
     def __init__(self,grade,major,banji,instructor):
        self.__grade = grade
        self.__major  = major
        self.__banji = banji
        self.__instructor = instructor

class Subject(object):
    def __init__(self,yuwen,math,yingyu):
        self.__yuwen = yuwen
        self.__math  = math
        self.__yingyu = yingyu

class People(Human,Student,Subject):
    pass

class adjustment(Human):
    def out(self, attribute, vlaue):
        if isinstance(attribute, str):  # 之前定义的属性类型只有字符串与整形两种
            if isinstance(vlaue, str):
                pass
            else:
                raise ValueError('Is not string type!')
        else:  # 反之就是整形了
            pass

接下来会继续做优化、逻辑判断等。请看下次总结。

猜你喜欢

转载自blog.csdn.net/m0_37801537/article/details/81144398