新网工在YESLAB   

IT技术专业学习平台
IT人才专业服务提供商

 

VUE考试注册预约电话:010-82608710

全国热线:400-004-8626

Python基础|类(五)

首页    技术博文    Python/Linux    Python基础|类(五)
 

接上回说:

★ 使用名称重整保护私有特性

前面的 Duck 列子中, 为了隐藏内部特性,我们曾将其命名为 hiddenname 。 其实,Python 对那些需要刻意隐藏在类内部的特性有自己的命名规范:
由连续的两个下划线开头(_)。

我们来把 hidden_name 改名为 __name,如下所示:

看看代码是否还能正常工作:

看起来没问题,现在,你无法在外部访问 __name 特性了:

这种命名规范本质上并没有把特性变成私有,但Python确实将它的名字重整了。让外部的代码无法使用。如果你是在好奇名称重整是怎么实现的。我可以偷偷告诉你其中的奥秘:

发现了么?我们并没有得到 inside the getter,成功绕过了 getter 方法。尽管如我们所见,这种保护特性的方式并不完美,但它确实能在一定程度上避免我们无意或有意地对特性进行直接访问。

★ 方法的类型

 

有些数据(特性)和函数(方法)是类本身的一部分,还有一些是由类创建的实例的一部分。

在类的定义中,以 self 作为第一个参数的方法都是实例方法(instance method)。它们在创建自定义类时最常用。实例方法的首个参数是 self,当它被调用时,Python 会把调用该方法的对象作为 self 参数传入。

与之相对,类方法(class method)会作用于整个类,对类作出的任何改变会对它的所有实例对象产生影响。在类定义内部,用前缀修饰符 @classmethod 指定的方法都是类方法。与实例方法相似,类方法的第一个参数是类本身。在Python中,这个采纳数常被写作 cls,因为全称 class 是保留字,在这里我们无法使用。下面的例子中,我们为A定义一个类方法来记录一共有多少个类A的对象被创建:

注意,上面的代码中,我们使用的是 A.count(类特性),而不是 self.count (可能是对象的特性)。在 kids() 方法中,我们使用的是 cls.count,它与 A.count 的作用一样。

类定义中的方法还存在着第三种类型,它既不会影响类也不会影响类的对象。他们出现在类的定义中仅仅是为了方便,否则他们只能孤零零地出现在代码的其他地方,这会影响代码的逻辑性。这种类型的方法被称作静态方法(static method),用 @staticmethod 修饰, 它既不需要 self 参数 也不需要 class 参数。 下面列子中的静态方法是一则 CoyoteWeapon的广告:

注意,在这个例子中,我们甚至都不用创建任何 CoyoteWeapon 类的对象就可以调用这个方法,语法优雅不失风格!

★ 鸭子类型

Python 对实现多态(polymorphism)要求得十分宽松,这意味着我们可以对不同对象调用同名的操作,甚至与用管这些对象的类型是什么。

我们来为上那个 Quote 类设定同样的初始化方法 init(),然后再添加两个新函数:

  • who() 返回保存的 person 字符串的值

  • says() 返回保存的 words 字符串的内容,并添上指定的表点符号。

它们的具体实现如下所示:

我们不需要改变 QuestionQuote 或者 ExclamQuote 的初始化方式,因此没有覆盖它们的 init()方法。Python 会自动调用父类 Quote 的初始化函数 init() 来存储实例变量 person 和 words,这就是我们可以在子类 QuestionQuote 和 ExclamationQuote 的对象里访问 self.words 的原因。

接下来创建一些对象:

三个不同版本的 says() 为上面三种类型提供了不同的相应方式,这是面向对象的语言中多态的传统形式。Python 在这方面走的更远一些,无论对象的种类是什么,只要包含 who() 和 says(),你便可以调用它。我们再来定义一个 BabblingBrook 类,他与我们之前的猎人猎物(Quote 类的后代)什么的没有任何关系:

现在,对不同对象执行 who() 和 says() 方法,其中有一个(brook) 与其他类型的对象毫无关联:

这种方式有事被称作鸭子类型(duck typing),这个命名源自一句名言:

在等放假的节奏了吗?

趁着这个时间温习下

2018年2月6日 18:00
浏览量:0
收藏