自学python之路 第六章

自学python之路

四川农业大学——大数据实验室第一次打卡

第六章

6.2 类和实例

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))
bart = Student('Bart Simpson',59)
lisa = Student('Lisa Simpson',87)
bart.print_score()
print_score(lisa)

·类的特点:第一个参数永远是实例变量self,并且,调用时不用传递该参数,其他参数正常传入。
·类的方法:在【Student】类的内部定义访问数据的函数,这样,就把“数据”给封装起来了,这些封装数据的函数是和【Student】类本身关联起来的,即为类的方法。

·封装的另外一个好处是可以给Student类增加新的方法,比如get_grade:

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)
bart.get_grade()            

小结

类是创建实例的模板,而实例则是一个个具体的对象,各个实例拥有的数据都互相独立,互不影响;
方法就是与实例绑定的函数,和普通函数不同,方法可以直接访问实例的数据;
通过在实例上调用方法,我们就直接操作了对象内部的数据,但无需知道方法内部的实现细节。
和静态语言不同,Python允许实例变量绑定任何数据,也就是说,对于两个实例变量,虽然他们都是同一个类的不同实例,但拥有的变量名称都可能不同:在这里插入图片描述

6.3 访问限制

·从前面的Student类的定义来看,外部代码还是可以自由的修改一个实例的name、score属性:
在这里插入图片描述

·如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问,如下:
在这里插入图片描述
·但是如果外部代码要获取name和score怎么办?可以给Student类增加get_name和get_score这样的方法:

def get_name(self):
        return self.__name
    def get_score(self):
        return self.__score

·如果要允许外部代码修改score,可添加set_score方法:

 def set_score(self,score):
        self.__score = score

·为什么要大费周章修改参数值,因为在此方法中,可以对参数做检查,避免传输无效的参数:

def set_score(self,score):
        if 0 <= score <= 100:
            self.__score = score
        else:
            raise ValueError('bad score')

继承和多态

·在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class):
在这里插入图片描述
·当子类和父类都存在相同的run()方法时,我们说,子类的run()覆盖了父类的run(),在代码运行的时候总是会调用子类的run()。这样,我们就获得了继承的另一个好处:多态。
在这里插入图片描述
·理解多态:(Dog可以看成Animal,但Animal不可以看成Dog)
在这里插入图片描述
·当我们传入DOG、CAT,由运行时该对象的确切类型决定,调用方只管调用,不管细节,而当我们新增一种Animal的子类时,只要确保run()方法编写正确,不管原来的代码是如何调用的。这就是著名的“开闭”原则:
对外扩展开放:允许新增Animal子类;
对修改封闭:不需要修改依赖Animal类型的run_twice等函数。
在这里插入图片描述
·静态语言vs动态语言
对于静态语言:如果需要传入Animal类型,则传入的对象必须是Animal类火灾它的子类,否则无法调用run()方法。对于动态语言:则不一定需要传入Animal类型,只需要保证传入的对象有一个run()方法就可以了。

小结

继承可以把父类的所有功能都直接都拿过来,这样就不必从零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写。

6.5 获取对象信息

·判断对象类型,使用type()判断;
也可使用isinstance(),相对前者的优势为:对于class的继承关系来说,使用type()就很不方便,可使用isinstance()函数。
·使用dir():如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list,比如,获得一个str对象的所有属性和方法。
在这里插入图片描述

·实际上,len()函数内部,它自动去调用该对象的__len__()方法。

小结

·通过内置的一系列函数,我们可以对任意一个Python对象进行剖析,拿到其内部的数据。要注意的是:只有在不知道对象信息的时候,我们才会去获取对象的信息。

6.6 实例属性和类属性

·给实例绑定属性的方法是通过实例变量,或者通过self变量:

class Student(object):
    def __init__(self,name):
        self.name = name
s = Student('Bob')
s.score = 90

·如果Student类本身需要绑定一个属性,可以直接在class中定义属性,这种属性是类属性,归Student类所有:

class Student(object):   
    name = 'Student'

·当我们定义了一个类属性之后,这个属性虽然归类所有,但是类的所有实例都可以访问到:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/EMIvv/article/details/105635127