美文网首页数据蛙数据分析每周作业
Python面向对象编程 -- 类和实例、访问限制

Python面向对象编程 -- 类和实例、访问限制

作者: 2023开始学 | 来源:发表于2019-04-21 19:24 被阅读0次

    面向对象编程

    Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。

    面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。

    而面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。

    类Class:

    类是对象的模板。即类是对一组有相同数据和相同操作的对象的定义,一个类所包含的方法和数据描述一组对象的共同属性和行为。

    类是在对象之上的抽象,对象则是类的具体化,是类的实例。类可有其子类,也可有其它类,形成类层次结构。

    任何类最终都可以追溯到根类object

    对象的方法(Method)

    给对象发消息实际上就是调用对象对应的关联函数,称之为对象的方法(Method).
    

    综上,面向对象的设计思想是抽象出Class,根据Class创建Instance。

           面向对象的抽象程度又比函数要高,因为一个Class既包含数据,又包含操作数据的方法。
    
           面向对象的三大特点:数据封装、继承、多态
    

    类和实例

    类是抽象的模板,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。

    定义类,Class关键字

    (1) 关键字class

    (2) 类名:通常是大写开头的单词,如Student

    (3)(继承类):表示该类是从哪个类继承下来的,通常,如果没有合适的继承类,就是用object类,这是所有类最终都会继承的类。

    注:当我们定义一个class的时候,实际上就定义了一种数据类型。定义的class数据类型和Python自带的数据类型没什么区别,比如str, dict, list。

    创建实例:类名+()

    1 #这是最简单的定义类
    2 class Student(object): 3     pass
    4 
    5 #创建一个实例
    6 bart=Student() 7 print(bart)</pre>
    

    运行结果:

    <main.Student object at 0x00000000010CC2E8>,变量bart指向Student的一个实例,后面的0x00000000010CC2E8是内存地址,每个object的地址都不一样。

    _ init _方法

    作用:绑定属性
    

    注意:特殊方法“init”前后分别有两个下划线!!!

    1,init方法的第一个参数永远是self,表示创建的实例本身,在init方法内部,把各种属性绑定到self

    2,有了init方法,在创建实例的时候,必须传入与init方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去。


    和普通函数相比,在类中定义的函数(不仅仅是init函数,包括后面类的方法函数,是指类中所有的定义函数),第一个参数永远是实例变量self,并且调用时,不用传递self参数

    数据封装

    类的方法

    在类的内部定义访问数据的函数,这样,就把“数据”给封装起来了,这些封装数据的函数是和类本身关联起来的,称为类的方法。

    实战

    class Student(object):
    
        def __init__(self, name, score):
            self.name = name
            self.score = score
    
        def print_score(self):
            print('%s: %s' % (self.name, self.score))
    
        def get_grade(self):
            if self.score >= 90:
                return 'A'
            elif self.score >= 60:
                return 'B'
            else:
                return 'C'
    
    bart = Student('Bart Simpson', 59)
    lisa = Student('Lisa Simpson', 87)
    
    print('bart.name =', bart.name)
    print('bart.score =', bart.score)
    bart.print_score()
    
    print('grade of Bart:', bart.get_grade())
    print('grade of Lisa:', lisa.get_grade())
    

    运行结果:


    image

    变量名

    特殊变量:以双下划线开头,并且以双下划线结尾的,是特殊变量,类似xxx,特殊变量是可以直接访问的,不是 Private变量,所以,在需要特殊变量的地方不能用namescore这样的变量名。

    私有变量(Private):有2种形式,一个下划线开头,两个下划线开头

    (1) 一个下划线开头:如_name

    这样的实例变量,外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思是:“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问。”

    (2)两个下划线开头:如__name

    双下划线开头的实例变量是不是一定不能从外部访问呢?

    答:也不是,不能直接访问__name,是因为python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量。

    但是强烈建议不要这么做,因为不同版本的Python解释器可能会把__name改成不同的变量名。

     总的来说,Python本身没有任何机制阻止你干坏事,一切全靠自觉。
    

    访问私有变量(Private)的方式:

    举例:

    bart=Student('bart simpon',98)
    
    image.png

    备注:1,空白处相当于新增变量,不会改变score的值

           2,可以访问,说明我们可以修改私有变量的值
    
           3,既然已经设置成私有变量了,应尽量不要随意访问
    

    访问私有变量方式代码实践:

    1个下划线的代码:

    class Student(object):
    
        def __init__(self, name, score):
            self._name = name
            self._score = score
    
        def print_score(self):
            print('Print语句返回值:%s: %s' % (self._name, self._score))
    
    
    bart=Student('bart simpon',98)
    
    print("这是1个下划线的私有变量:")
    bart.score=45
    print("bart.score:",bart.score)
    print("bart.print_score():",bart.print_score())
    print("")
    
    
    bart.__score=45
    print("bart.__score:",bart.__score)
    print("bart.print_score():",bart.print_score())
    print("")
    
    
    bart._Student_score=45
    print("bart._Student_score:",bart._Student_score)
    print("bart.print_score():",bart.print_score())
    print("")
    
    
    bart._Student__score=45
    print("bart._Student__score:",bart._Student__score)
    print("bart.print_score():",bart.print_score())
    print("")
    
    bart._score=45
    print("bart._score:",bart._score)
    print("bart.print_score():",bart.print_score())
    
    

    一个下划线: 只有bart._score能修改_score的值

    image

    2个下划线的代码:

    class Student(object):
    
        def __init__(self, name, score):
            self.__name = name
            self.__score = score
    
        def print_score(self):
            print('Print语句返回值:%s: %s' % (self.__name, self.__score))
    
    
    
    
    bart=Student('bart simpon',98)
    # print("gds",bart.print_score())
    print("这是2个下划线的私有变量:")
    bart.score=45
    print("bart.score:",bart.score)
    print("bart.print_score():",bart.print_score())
    print("")
    
    
    bart._score=45
    print("bart._score:",bart._score)
    print("bart.print_score():",bart.print_score())
    print("")
    
    
    bart.__score=45
    print("bart.__score:",bart.__score)
    print("bart.print_score():",bart.print_score())
    print("")
    
    
    bart._Student_score=45
    print("bart._Student_score:",bart._Student_score)
    print("bart.print_score():",bart.print_score())
    print("")
    
    
    bart._Student__score=45
    print("bart._Student__score:",bart._Student__score)
    print("bart.print_score():",bart.print_score())
    

    2个下划线: 只有bart._Student__score能修改__score的值

    image

    如果要使内部属性不被外部访问,可以在属性名前加两个下划线__,变成私有变量,只有内部可以访问,外部不能访问。

    这样确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护,代码更加健壮。

    如果外部代码要获取name和score怎么办?可以给Student类增加get_name和get_score这样的方法。

    如果外部代码要修改score怎么办?可以给Student类增加get_score方法。

    代码如下:

    class Student(object):
    
        def __init__(self, name, score):
            self.__name = name
            self.__score = score
    
        def print_score(self):
            print('%s: %s' % (self.__name, self.__score))
    
        def get_name(self):
            return self.__name
    
        def get_score(self):
            return self.__score
    
        def set_score(self, score): #使用这种方法修改属性值,可以检查传入的参数值是否有问题
            if 0 <= score <= 100:
                self.__score = score
            else:
                raise ValueError('bad score')
    
    bart = Student('Bart Simpson', 59)
    print("bart._Student__score:",bart._Student__score)  #这种就运行正确了
    
    print("bart.get_score():",bart.get_score())
    
    print(bart.score)  #运行结果出错,提示'Student' object has no attribute 'score'
    
    # print(bart.__score)   #运行结果出错,提示'Student' object has no attribute '__score'
    

    运行结果:

    image
    问题:为什么一个、两个下划线的地方,print( bart.score )能运行出结果,而这最近的一段代码中print( bart.score )却报错?

    答:前者是相当于新增加了一个变量,所以能运行出结果,而后者的print( bart.score )这种访问形式是不能直接访问私有变量,所以报错,而print( bart._Student__score )却访问成功了

    来源:https://www.liaoxuefeng.com/

    相关文章

      网友评论

        本文标题:Python面向对象编程 -- 类和实例、访问限制

        本文链接:https://www.haomeiwen.com/subject/rdjswqtx.html