(翻译)30天学习Python👨‍💻第十天——面向对象补充

30天学习Python:man:‍:computer:第十天——面向对象补充

昨天探讨了面向对象所有重要的概念。今天我会探讨面向对象剩下的概念以及它们在Python中的实现。除此之外,我尝试用一些涵盖面向对象所有概念用法的编程练习来稳固之前所有的概念。

Super()

super
是Python中的一个保留字(在Python2.2中被引入),在继承中使用。当一个子类继承自一个父类,并且需要调用这个父类上的方法时,就需要用到 super
。这样听起来可能让人有些疑惑,来看一个例子:

不使用 super

class Employee:
def __init__(self, name):
self.name = name
print(f'{self.name} is an employee')
class Manager(Employee):
def __init__(self, department, name):
self.department = department
self.name = name
Employee.__init__(self, name) # 调用父类的构造函数
print(f'Manager, {self.department} department')
staff_1 = Manager('HR', 'Andy')
# Andy is an employee
# Manager, HR department
复制代码

在这个例子中,父类的 __init__
构造方法用类名调用, self
对象作为第一个参数被传入。

使用 super
(注意它不需要传入参数 self

class Employee:
def __init__(self, name):
self.name = name
print(f'{self.name} is an employee')
class Manager(Employee):
def __init__(self, department, name):
self.department = department
self.name = name
super().__init__(name) # 调用父类的构造函数
print(f'Manager, {self.department} department')
staff_1 = Manager('HR', 'Andy')
# Andy is an employee
# Manager, HR department
复制代码

像上面代码中的构造方法一样,父类的任何方法在子类中都能够使用 super()
调用。

在JavaScript中,语法更简单一点, super
的调用方式类似 super(parameter)
这样。但是我喜欢Python的语法。使用 super
调用 __init__
方法更加清楚。

内省

Python能够计算在运行时计算对象的类型(在Python中一切皆对象)。这意味着编译器在运行时能够动态的理解对象的属性和方法。这叫做 内省

Python提供了一个内置函数 dir
来对一个对象进行内省。

class Developer:
def __init__(self, name, language):
self.name = name
self.language = language
def introduce(self):
print(f'Hi! I am {self.name}. I code in {self.language}')
dev = Developer('Matt', 'Python')
print(dir(dev))
复制代码

魔术方法

在Python中,通过定义一些 魔术方法
类会变得更加强大。这些方法名的前面和后面都有两个 __
,在Python中被预先定义,有着特殊的用途。例如,我们可以访问内置函数,因为它被定义为一个特殊的魔术方法 __len__

class Sentence:
words = []
def add_word(self, word):
self.words.append(word)
def __len__(self):
return len(self.words)
new_sentence = Sentence()
new_sentence.add_word('Hello')
new_sentence.add_word('World')
print(len(new_sentence))
复制代码

我修改了 Sentence
类,这样我们就可以使用内置方法 len
,默认情况下, len
不能用于实现自定义逻辑。魔术方法看上去非常的方便。

多继承

一个类从多个类中继承属性和方法是有可能的。多继承是一个强大的概念,但也是危险的。在JavaScript中,多继承是不被支持的。

class Batsman:
def swing_bat(self):
return 'What a shot!'
class Bowler:
def bowl_bouncer(self):
return 'What a bouncer!'
class AllRounder(Batsman, Bowler):
pass
player = AllRounder()
print(player.bowl_bouncer()) # What a shot!
print(player.swing_bat()) # What a bouncer!
复制代码

当父类有需要初始化的构造函数方法时,它可能会变得有点复杂。在子类中,它所继承所有类的构造函数方法都需要初始化。

class Batsman:
def __init__(self, hitting_power):
self.hitting_power = hitting_power
def swing_bat(self):
return f'Shot with power {self.hitting_power}'
class Bowler:
def __init__(self, delivery_speed):
self.delivery_speed = delivery_speed
def bowl_bouncer(self):
return f'Bowled with speed of {self.delivery_speed} kmph'
class AllRounder(Batsman, Bowler):
def __init__(self, hitting_power, delivery_speed):
Batsman.__init__(self, hitting_power)
Bowler.__init__(self, delivery_speed)
player = AllRounder(90, 80)
print(player.swing_bat())
print(player.bowl_bouncer())
复制代码

方法解析顺序

方法解析顺序或简称 mro
,是Python中属性和方法继承的顺序。

当从多个类继承时,属性和方法由特定层次结构中的子类继承。Python中实现此功能的底层算法使用深度优先搜索算法。

class Employee:
secret_code = 'secret'
class Manager(Employee):
secret_code = 'm123'
class Accountant(Employee):
secret_code = 'a123'
class Owner(Manager, Accountant):
pass
person = Owner()
print(person.secret_code) # m123
复制代码

为了了解继承顺序,Python提供了一个方法 mro
,可以在对象上调用该方法来查看继承的层次结构。

多继承可能很难理解,所以这种模式在实践中并不常用。

这就是今天所有的内容了。最后讲完了Python中的面向对象编程概念。我们的目标是在这个挑战结束后,开始构建真正的Python项目时使用这些原则。

我希望我能够涵盖Python中所有关键的面向对象编程概念,并且解释的足够通俗易懂。

明天我们将进入Python函数式编程的领域。肯定会很有趣。总的来说,Python是一种程序语言,并且因其面向对象的概念而受到欢迎,在本周余下的时间里,我们将探索如何用Python实现函数式编程概念。

原文链接

30 Days of Python :man:‍:computer: – Day 10 – OOP Missing Pieces

稀土掘金
我还没有学会写个人说明!
上一篇

张量tensor:机器学习的基本数据结构介绍 - Santiago

下一篇

PyMICROPSIA:AridViper开发的新型信息窃取木马

你也可能喜欢

评论已经被关闭。

插入图片