写点什么

笔记 -python 面向对象

用户头像
许有加
关注
发布于: 15 小时前

#python-面向对象

##类和实例

定义类是通过 class 关键字自由地给一个实例变量绑定属性通过定义一个特殊的__init__方法,在创建实例的时候,就把 name,score 等属性绑上去注意到__init__方法的第一个参数永远是 self,表示创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到 self,因为 self 就指向创建的实例本身有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但 self 不需要传,Python 解释器自己会把实例变量传进去面向对象编程的一个重要特点就是数据封装通过在实例上调用方法,我们就直接操作了对象内部的数据,但无需知道方法内部的实现细节。和静态语言不同,Python 允许对实例变量绑定任何数据,也就是说,对于两个实例变量,虽然它们都是同一个类的不同实例,但拥有的变量名称都可能不同 ##访问限制如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__在 Python 中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问注意:在 Python 中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是 private 变量,所以,不能用__name__、__score__这样的变量名有些时候,你会看到以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name 是因为 Python 解释器对外把__name 变量改成了_Student__name,所以,仍然可以通过_Student__name 来访问__name 变量表面上看,外部代码“成功”地设置了__name 变量,但实际上这个__name 变量和 class 内部的__name 变量不是一个变量!内部的__name 变量已经被 Python 解释器自动改成了_Student__name,而外部代码给 bart 新增了一个__name 变量

bart = Student('Bart Simpson', 59)bart.get_name()'Bart Simpson'bart.__name = 'New Name' # 设置__name变量!bart.__name'New Name'
复制代码


##获取对象信息来判断对象类型,使用 type()如果一个变量指向函数或者类,也可以用 type()对于 class 的继承关系来说,使用 type()就很不方便。我们要判断 class 的类型,可以使用 isinstance()函数如果要获得一个对象的所有属性和方法,可以使用 dir()函数,它返回一个包含字符串的 list 类似__xxx__的属性和方法在 Python 中都是有特殊用途的,比如__len__方法返回长度。在 Python 中,如果你调用 len()函数试图获取一个对象的长度,实际上,在 len()函数内部,它自动去调用该对象的__len__()方法 :len('ABC') 等价于 'ABC'.len()


配合getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态如果试图获取不存在的属性,会抛出AttributeError的错误
def readImage(fp):if hasattr(fp, 'read'): return readData(fp)return None
复制代码


##继承和多态继承的好处:最大的好处是子类获得了父类的全部功能继承的第二个好处需要我们对代码做一点改进,可以根据子类实际情况修改从父类继承的方法多态:当子类和父类都存在相同的 run()方法时,我们说,子类的 run()覆盖了父类的 run(),在代码运行的时候,总是会调用子类的 run()当我们需要传入 Dog、Cat、Tortoise……时,我们只需要接收 Animal 类型就可以了,因为 Dog、Cat、Tortoise……都是 Animal 类型,然后,按照 Animal 类型进行操作即可。由于 Animal 类型有 run()方法,因此,传入的任意类型,只要是 Animal 类或者子类,就会自动调用实际类型的 run()方法判断一个变量是否是某个类型可以用 isinstance()##实例属性和类属性由于 Python 是动态语言,根据类创建的实例可以任意绑定属性在编写程序的时候,千万不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性实例属性属于各个实例所有,互不干扰;类属性属于类所有,所有实例共享一个属性;不要对实例属性和类属性使用相同的名字,否则将产生难以发现的错误


##静态语言 vs 动态语言对于静态语言(例如 Java)来说,如果需要传入 Animal 类型,则传入的对象必须是 Animal 类型或者它的子类,否则,将无法调用 run()方法。对于 Python 这样的动态语言来说,则不一定需要传入 Animal 类型。我们只需要保证传入的对象有一个 run()方法就可以了:动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子动态语言的鸭子类型特点决定了继承不像静态语言那样是必须的


用户头像

许有加

关注

还未添加个人签名 2019.02.11 加入

还未添加个人简介

评论

发布
暂无评论
笔记-python面向对象