机器人 救救瓜
Toggle navigation
Home
SCM-tool
Linux
Jenkins
SVN
other
About Me
Archives
Tags
python 笔记之 多态、封装、方法、属性、超类和继承
2021-03-10 17:12:12
472
0
0
gua_l
多态、封装、方法、属性、超类和继承 ### 多态 每当无需知道对象是什么样的就能对其执行操作时,都是多态在起作用 ``` >>> 'abc'.count('a') 1 >>> [1, 2, 'a'].count('a') 1 ``` 如果有一个变量x,你无需知道它是字符串还是列表就能调用方法count:只要你向这个方法提供一个字符作为参数,它就能正常运行。 多态形式是Python编程方式的核心,有时称为鸭子类型。这个术语源自如下说法:“如果走起来像鸭子,叫起来像鸭子,那么它就是鸭子。”有关鸭子类型的详细信息,请参阅http://en.wikipedia.org/wiki/Duck_typing。 ### 封装 封装(encapsulation)指的是向外部隐藏不必要的细节。这听起来有点像多态(无需知道对象的内部细节就可使用它)。这两个概念很像,因为它们都是抽象的原则。它们都像函数一样,可帮助你处理程序的组成部分,让你无需关心不必要的细节。但封装不同于多态。多态让你无需知道对象所属的类(对象的类型)就能调用其方法,而封装让你无需知道对象的构造就能使用它。 如果 o将其名称存储在全局变量global_name中,如果尝试创建多个OpenObject对象,将出现问题,因为它们共用同一个变量。避免干扰全局变量,就需要将名称“封装”在对象中。使用属性而非全局变量。 ### 类 在Python中,表示类约定使用**单**数并将**首字母大写**,如Bird和Lark。 在较旧的Python版本中,类型和类之间泾渭分明:内置对象是基于类型的,而自定义对象是基于类的。因此,你可以创建类,但不能创建类型。在较新的Python 2版本中,这种差别不那么明显。**在Python 3中,已不再区分类和类型了。** ### 隐藏 如果能直接访问ClosedObject(对象c所属的类)的属性name,就不需要创建方法setName和getName了。关键是其他程序员可能不知道(也不应知道)对象内部发生的情况。例如,ClosedObject可能在对象修改其名称时向管理员发送电子邮件。这种功能可能包含在方法set_name中。但如果直接设置c.name,结果将如何呢?什么都不会发生——根本不会发送电子邮件。为避免这类问题,可将属性定义为私有。私有属性不能从对象外部访问,而只能通过**存取器**方法(如get_name和set_name)来访问。 如果你不希望名称被修改,又想发出不要从外部修改属性或方法的信号,可用一个下划线打头。这虽然只是一种约定,但也有些作用。例如,from module import *不会导入以一个下划线打头的名称。 ### 类的作用域 在类作用域内定义了一个变量,所有的成员(实例)都可访问它,这里使用它来计算类实例的数量。 ### 继承 要确定一个类是否是另一个类的子类,可使用内置方法issubclass。 ``` >>> issubclass(SPAMFilter, Filter) True >>> issubclass(Filter, SPAMFilter) False ``` 如果你有一个类,并想知道它的基类,可访问其特殊属性__bases__。 ``` >>> SPAMFilter.__bases__ (<class __main__.Filter at 0x171e40>,) >>> Filter.__bases__ (<class 'object'>,) ``` 如果你要获悉对象属于哪个类,可使用属性__class__。 ``` >>> s.__class__ <class __main__.SPAMFilter at 0x1707c0> ``` ### 查看对象存储的方法 属性 ``` dir(list) ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] list.__dict__ mappingproxy({'__repr__': <slot wrapper '__repr__' of 'list' objects>, '__hash__': None, '__getattribute__': <slot wrapper '__getattribute__' of 'list' objects>, '__lt__': <slot wrapper '__lt__' of 'list' objects>, '__le__': <slot wrapper '__le__' of 'list' objects>, '__eq__': <slot wrapper '__eq__' of 'list' objects>, '__ne__': <slot wrapper '__ne__' of 'list' objects>, '__gt__': <slot wrapper '__gt__' of 'list' objects>, '__ge__': <slot wrapper '__ge__' of 'list' objects>, '__iter__': <slot wrapper '__iter__' of 'list' objects>, '__init__': <slot wrapper '__init__' of 'list' objects>, '__len__': <slot wrapper '__len__' of 'list' objects>, '__getitem__': <method '__getitem__' of 'list' objects>, '__setitem__': <slot wrapper '__setitem__' of 'list' objects>, '__delitem__': <slot wrapper '__delitem__' of 'list' objects>, '__add__': <slot wrapper '__add__' of 'list' objects>, '__mul__': <slot wrapper '__mul__' of 'list' objects>, '__rmul__': <slot wrapper '__rmul__' of 'list' objects>, '__contains__': <slot wrapper '__contains__' of 'list' objects>, '__iadd__': <slot wrapper '__iadd__' of 'list' objects>, '__imul__': <slot wrapper '__imul__' of 'list' objects>, '__new__': <built-in method __new__ of type object at 0x000007FEDADB6D30>, '__reversed__': <method '__reversed__' of 'list' objects>, '__sizeof__': <method '__sizeof__' of 'list' objects>, 'clear': <method 'clear' of 'list' objects>, 'copy': <method 'copy' of 'list' objects>, 'append': <method 'append' of 'list' objects>, 'insert': <method 'insert' of 'list' objects>, 'extend': <method 'extend' of 'list' objects>, 'pop': <method 'pop' of 'list' objects>, 'remove': <method 'remove' of 'list' objects>, 'index': <method 'index' of 'list' objects>, 'count': <method 'count' of 'list' objects>, 'reverse': <method 'reverse' of 'list' objects>, 'sort': <method 'sort' of 'list' objects>, '__doc__': 'Built-in mutable sequence.\n\nIf no argument is given, the constructor creates a new empty list.\nThe argument must be an iterable if specified.'}) list.__class__ ``` ### 抽象类 一般而言,抽象类是不能(至少是不应该)实例化的类,其职责是定义子类应实 现的一组抽象方法。下面是一个简单的示例: ``` from abc import ABC, abstractmethod class Talker(ABC): @abstractmethod def talk(self): pass ``` 形如@this的东西被称为装饰器,其用法将在第9章详细介绍。这里的要点是你使用 @abstractmethod来将方法标记为抽象的——在子类中必须实现的方法。 抽象类(即包含抽象方法的类)最重要的特征是不能实例化。 换而言之,应将isinstance返回True视为一种意图表达。在这里,Clam有成为Talker的意图。本着鸭子类型的精神,我们相信它能承担Talker的职责,但可悲的是它失败了。将Herring注册为Talker(而不从Herring和Talker派生出子类),这样所有的Herring对象都将被视为Talker对象这种做法存在一个缺点,就是直接从抽象类派生提供的保障没有了。
Pre:
python 笔记之 构造函数 存取方法 生成器 迭代器
Next:
python 笔记之 python 断言 并行迭代 pass、del和exec ,exec 和 eval
0
likes
472
Weibo
Wechat
Tencent Weibo
QQ Zone
RenRen
Submit
Sign in
to leave a comment.
No Leanote account?
Sign up now.
0
comments
More...
Table of content
No Leanote account? Sign up now.