介绍
在这个实验中,你将学习如何在 Python 中检查一个对象是否具有某个特定的方法。本实验涵盖对象方法,重点介绍它们如何将行为封装在对象内部,以实现代码的组织性和可重用性。
你将探索 Dog 类,该类包含 __init__、bark 和 get_name 等方法,创建实例并调用这些方法。然后,实验将指导你使用 hasattr() 和 callable() 来确定一个对象是否拥有特定的方法。最后,你将了解方法解析顺序(Method Resolution Order,MRO)。
了解对象方法
在这一步中,你将了解 Python 中的对象方法。方法是与对象关联的函数,用于对对象的数据执行操作。理解对象方法对于在 Python 中使用对象和类至关重要。
让我们从创建一个名为 Dog 的简单类开始:
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed
def bark(self):
return "Woof!"
def get_name(self):
return self.name
使用 VS Code 编辑器在你的 ~/project 目录中创建一个名为 dog.py 的文件。将上述代码复制并粘贴到 dog.py 文件中。
这个类有三个方法:
__init__:这是构造方法。当创建类的新对象时会调用它,用于初始化对象的属性。bark:这个方法返回字符串 "Woof!"。get_name:这个方法返回狗的名字。
现在,让我们创建 Dog 类的一个对象并调用它的方法。在 ~/project 目录中创建一个名为 main.py 的新文件:
from dog import Dog
my_dog = Dog("Buddy", "Golden Retriever")
print(my_dog.bark())
print(my_dog.get_name())
保存 main.py 文件。
要运行 main.py 脚本,请打开终端并导航到 ~/project 目录:
cd ~/project
然后,使用 python 命令执行脚本:
python main.py
你应该会看到以下输出:
Woof!
Buddy
在这个例子中,my_dog 是 Dog 类的一个对象。我们使用点号表示法 (.) 在 my_dog 对象上调用 bark 和 get_name 方法。
对象方法允许你将行为封装在对象内部,使你的代码更具组织性和可重用性。它们是 Python 面向对象编程的基础部分。
使用 hasattr() 和 callable() 进行检查
在这一步中,你将学习如何在 Python 中使用 hasattr() 和 callable() 函数。这些函数对于检查对象以及确定它们是否具有特定的属性或方法非常有用。
hasattr(object, attribute_name):此函数用于检查对象是否具有给定的属性。如果属性存在,则返回True;否则返回False。callable(object):此函数用于检查对象是否可调用(即可以像函数一样被调用)。如果对象可调用,则返回True;否则返回False。
让我们继续使用上一步中的 Dog 类。使用 VS Code 编辑器打开 ~/project 目录中的 dog.py 文件,其内容应该如下:
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed
def bark(self):
return "Woof!"
def get_name(self):
return self.name
现在,让我们在 ~/project 目录中创建一个名为 check_methods.py 的新文件,以演示 hasattr() 和 callable() 的用法:
from dog import Dog
my_dog = Dog("Buddy", "Golden Retriever")
print(hasattr(my_dog, "name"))
print(hasattr(my_dog, "bark"))
print(hasattr(my_dog, "age"))
print(callable(my_dog.bark))
print(callable(my_dog.name))
保存 check_methods.py 文件。
在这个示例中:
hasattr(my_dog, "name")检查my_dog对象是否具有名为"name"的属性。由于Dog类有一个name属性,因此它将返回True。hasattr(my_dog, "bark")检查my_dog对象是否具有名为"bark"的属性。由于Dog类有一个bark方法,因此它将返回True。hasattr(my_dog, "age")检查my_dog对象是否具有名为"age"的属性。由于Dog类没有age属性,因此它将返回False。callable(my_dog.bark)检查my_dog.bark属性是否可调用(即它是一个方法)。由于bark是一个方法,因此它将返回True。callable(my_dog.name)检查my_dog.name属性是否可调用。由于name是一个字符串属性,而不是方法,因此它将返回False。
要运行 check_methods.py 脚本,请打开终端并导航到 ~/project 目录:
cd ~/project
然后,使用 python 命令执行脚本:
python check_methods.py
你应该会看到以下输出:
True
True
False
True
False
这些函数对于编写更健壮、更灵活的代码非常有用,这些代码可以处理不同类型的对象和属性。
理解方法解析顺序(MRO)
在这一步中,你将了解 Python 中的方法解析顺序(Method Resolution Order,MRO)。MRO 是 Python 在类层次结构中搜索方法的顺序。在处理多重继承时,它尤为重要。
让我们创建一组新的类来演示 MRO。使用 VS Code 编辑器在你的 ~/project 目录中创建一个名为 animal.py 的文件:
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "Generic animal sound"
class Mammal(Animal):
def speak(self):
return "Generic mammal sound"
class Dog(Mammal):
def speak(self):
return "Woof!"
class Cat(Mammal):
def speak(self):
return "Meow!"
保存 animal.py 文件。
现在,让我们在 ~/project 目录中创建一个名为 mro_example.py 的新文件,以演示 MRO:
from animal import Animal, Mammal, Dog, Cat
my_dog = Dog("Buddy")
my_cat = Cat("Whiskers")
print(my_dog.speak())
print(my_cat.speak())
保存 mro_example.py 文件。
在这个示例中:
Animal是具有speak方法的基类。Mammal继承自Animal并覆盖了speak方法。Dog继承自Mammal并覆盖了speak方法。Cat继承自Mammal并覆盖了speak方法。
当你调用 my_dog.speak() 时,Python 首先在 Dog 类中查找 speak 方法。如果在那里没有找到,它会在 Mammal 类中查找,然后在 Animal 类中查找。这个顺序由 MRO 决定。
要运行 mro_example.py 脚本,请打开终端并导航到 ~/project 目录:
cd ~/project
然后,使用 python 命令执行脚本:
python mro_example.py
你应该会看到以下输出:
Woof!
Meow!
现在,让我们探索一个更复杂的多重继承示例。在 ~/project 目录中创建一个名为 mro_complex.py 的新文件:
class A:
def method(self):
return "A"
class B(A):
def method(self):
return "B"
class C(A):
def method(self):
return "C"
class D(B, C):
pass
d = D()
print(d.method())
print(D.mro())
保存 mro_complex.py 文件。
在这个示例中:
- 类
D同时继承自B和C。 B和C都继承自A。method方法在A、B和C这三个类中都有定义。
要运行 mro_complex.py 脚本,请打开终端并导航到 ~/project 目录:
cd ~/project
然后,使用 python 命令执行脚本:
python mro_complex.py
你应该会看到以下输出:
B
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
输出 B 表明调用了类 B 的 method 方法。D.mro() 方法返回一个元组,表示类 D 的方法解析顺序。在这种情况下,MRO 是 D -> B -> C -> A -> object。这意味着当你调用 d.method() 时,Python 首先在类 D 中查找该方法,然后在类 B 中查找,接着在类 C 中查找,再在类 A 中查找,最后在基类 object 中查找。
理解 MRO 对于在使用继承(尤其是多重继承)时预测代码的行为至关重要。
总结
在本次实验中,第一步着重于理解 Python 中的对象方法。它引入了方法的概念,即与对象关联的函数,这对于对对象数据执行操作至关重要。创建了一个 Dog 类,其中包含 __init__、bark 和 get_name 等方法,以演示方法如何将行为封装在对象内部。
接着,实验引导你创建 Dog 类的一个实例,并使用点号表示法调用其方法,展示了对象方法如何为面向对象编程中的代码组织和复用做出贡献。



