💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# Python 中的面向对象编程 > 原文: [http://zetcode.com/lang/python/oop/](http://zetcode.com/lang/python/oop/) 在 Python 教程的这一部分中,我们将讨论 Python 中的面向对象编程。 那里有三种广泛使用的编程示例:过程编程,函数编程和面向对象的编程。 Python 支持所有三种编程示例。 ## 面向对象编程 面向对象编程(OOP)是一种使用对象及其相互作用设计应用和计算机程序的编程示例。 OOP 中有一些基本的编程概念: * 抽象 * 多态 * 封装 * 继承 抽象通过建模适合该问题的类来简化复杂的现实。 多态是将运算符或函数以不同方式用于不同数据输入的过程。 封装对其他对象隐藏了类的实现细节。 继承是一种使用已经定义的类形成新类的方法。 ## Python 对象 Python 中的所有内容都是一个对象。 对象是 Python OOP 程序的基本构建块。 `object_types.py` ```py #!/usr/bin/env python # object_types.py import sys def function(): pass print(type(1)) print(type("")) print(type([])) print(type({})) print(type(())) print(type(object)) print(type(function)) print(type(sys)) ``` 在此示例中,我们显示所有这些实体实际上都是对象。 `type()`函数返回指定对象的类型。 ```py $ ./object_types.py <class 'int'> <class 'str'> <class 'list'> <class 'dict'> <class 'tuple'> <class 'type'> <class 'function'> <class 'module'> ``` 整数,字符串,列表,字典,元组,函数和模块是 Python 对象。 ## Python `class`关键字 先前的对象都是 Python 编程语言的内置对象。 用户定义的对象是使用`class`关键字创建的。 该类是定义未来对象性质的蓝图。 从类中,我们构造实例。 实例是从特定类创建的特定对象。 例如,`Huck`可能是`Dog`类的实例。 `first_object.py` ```py #!/usr/bin/env python # first_object.py class First: pass fr = First() print(type(fr)) print(type(First)) ``` 这是我们的头等舱。 该类的主体暂时留空。 按照惯例,给类起一个以大写字母开头的名称。 ```py class First: pass ``` 在这里,我们定义`First`类。 请注意,默认情况下,所有类均从基`object`继承。 ```py fr = First() ``` 在这里,我们创建`First`类的新实例。 换句话说,我们实例化了`First`类。 `fr`是对我们新对象的引用。 ```py $ ./first_object.py <class '__main__.First'> <class 'type'> ``` 在这里,我们看到`fr`是`First`类的实例对象。 在类内部,我们可以定义属性和方法。 属性是对象的特征。 例如,这可以是雇员的工资。 方法定义了我们可以对对象执行的操作。 一种方法可以定义取消帐户。 从技术上讲,属性是变量,方法是在类内部定义的函数。 ## Python 对象初始化 称为`__init__()`的特殊方法用于初始化对象。 `object_initialization.py` ```py #!/usr/bin/env python # object_initialization.py class Being: def __init__(self): print("Being is initialized") Being() ``` 我们有一个`Being`类。 创建对象后立即自动调用特殊方法`__init__()`。 ```py $ ./object_initialization.py Being is initialized ``` 这是示例输出。 ## Python 对象属性 属性是对象的特征。 在`__init__()`方法中设置属性。 `attributes.py` ```py #!/usr/bin/env python # attributes.py class Cat: def __init__(self, name): self.name = name missy = Cat('Missy') lucky = Cat('Lucky') print(missy.name) print(lucky.name) ``` 在此代码示例中,我们有一个`Cat`类。 创建对象后立即自动调用特殊方法`__init__()`。 ```py def __init__(self, name): ``` 类定义中的每个方法都以对实例对象的引用开头。 按照惯例,它的名称为`self`。 `self`名称没有什么特别的。 例如,我们可以这样命名。 第二个参数`name`是自变量。 该值在类初始化期间传递。 ```py self.name = name ``` 在这里,我们将属性传递给实例对象。 ```py missy = Cat('Missy') lucky = Cat('Lucky') ``` 在这里,我们创建两个对象:猫`Missy`和`Lucky`。 参数的数量必须与类定义的`__init__()`方法相对应。 `"Missy"`和`"Lucky"`字符串成为`__init__()`方法的`name`参数。 ```py print(missy.name) print(lucky.name) ``` 在这里,我们打印两个猫对象的属性。 一个类的每个实例可以有自己的属性。 ```py $ ./attributes.py Missy Lucky ``` 可以动态分配属性,而不仅仅是在初始化过程中。 下一个示例对此进行了说明。 `attributes_dynamic.py` ```py #!/usr/bin/env python # attributes_dynamic.py class Person: pass p = Person() p.age = 24 p.name = "Peter" print("{0} is {1} years old".format(p.name, p.age)) ``` 我们定义并创建一个空的`Person`类。 ```py p.age = 24 p.name = "Peter" ``` 在这里,我们动态创建两个属性:`age`和`name`。 ```py $ ./attributes_dynamic.py 24 is Peter years old ``` ## Python 类属性 到目前为止,我们一直在讨论实例属性。 在 Python 中,还有所谓的类对象属性。 类的所有实例的类对象属性都相同。 `class_attribute.py` ```py #!/usr/bin/env python # class_attribute.py class Cat: species = 'mammal' def __init__(self, name, age): self.name = name self.age = age missy = Cat('Missy', 3) lucky = Cat('Lucky', 5) print(missy.name, missy.age) print(lucky.name, lucky.age) print(Cat.species) print(missy.__class__.species) print(lucky.__class__.species) ``` 在我们的示例中,我们有两只具有特定`name`和`age`属性的猫。 两只猫都有一些共同之处。 小姐和幸运者都是哺乳动物。 这反映在类级别属性`species`中。 该属性是在类主体中的任何方法名称之外定义的。 ```py print(Cat.species) print(missy.__class__.species) ``` 有两种方法可以访问类对象属性:通过`Cat`类的名称,或借助特殊的`__class__`属性。 ```py $ ./class_attribute.py Missy 3 Lucky 5 mammal mammal mammal ``` ## Python 方法 方法是在类主体内定义的函数。 它们用于通过对象的属性执行操作。 在 OOP 范式的封装概念中,方法至关重要。 例如,我们的`AccessDatabase`类中可能有一个`connect()`方法。 我们无需知道方法连接如何准确地连接到数据库。 我们只知道它用于连接数据库。 这对于划分编程中的职责至关重要,尤其是在大型应用中。 `methods.py` ```py #!/usr/bin/env python # methods.py class Circle: pi = 3.141592 def __init__(self, radius=1): self.radius = radius def area(self): return self.radius * self.radius * Circle.pi def setRadius(self, radius): self.radius = radius def getRadius(self): return self.radius c = Circle() c.setRadius(5) print(c.getRadius()) print(c.area()) ``` 在代码示例中,我们有一个`Circle`类。 我们定义了三种新方法。 ```py def area(self): return self.radius * self.radius * Circle.pi ``` `area()`方法返回圆的面积。 ```py def setRadius(self, radius): self.radius = radius ``` `setRadius()`方法为`radius`属性设置新值。 ```py def getRadius(self): return self.radius ``` `getRadius()`方法返回当前半径。 ```py c.setRadius(5) ``` 在实例对象上调用该方法。 `c`对象与类定义的`self`参数配对。 数字 5 与`radius`参数配对。 ```py $ ./methods.py 5 78.5398 ``` 在 Python 中,我们可以通过两种方式调用方法。 有有界的和无界的方法调用。 `bound_unbound_methods.py` ```py #!/usr/bin/env python # bound_unbound_methods.py class Methods: def __init__(self): self.name = 'Methods' def getName(self): return self.name m = Methods() print(m.getName()) print(Methods.getName(m)) ``` 在此示例中,我们演示了两个方法调用。 ```py print(m.getName()) ``` 这是绑定的方法调用。 Python 解释器会自动将`m`实例与`self`参数配对。 ```py print(Methods.getName(m)) ``` 这是无界的方法调用。 实例对象已显式提供给`getName()`方法。 ```py $ ./bound_unbound_methods.py Methods Methods ``` ## Python 继承 继承是一种使用已经定义的类形成新类的方法。 新形成的类称为派生的类,我们从中衍生的类称为基类。 继承的重要好处是代码重用和降低程序的复杂性。 派生类(后代)将覆盖或扩展基类(祖先)的功能。 `inheritance.py` ```py #!/usr/bin/env python # inheritance.py class Animal: def __init__(self): print("Animal created") def whoAmI(self): print("Animal") def eat(self): print("Eating") class Dog(Animal): def __init__(self): super().__init__() print("Dog created") def whoAmI(self): print("Dog") def bark(self): print("Woof!") d = Dog() d.whoAmI() d.eat() d.bark() ``` 在此示例中,我们有两个类:`Animal`和`Dog`。 `Animal`是基类,`Dog`是派生类。 派生类继承基类的功能。 通过`eat()`方法显示。 派生的类修改了基类的现有行为,如`whoAmI()`方法所示。 最后,派生类通过定义新的`bark()`方法来扩展基类的功能。 ```py class Dog(Animal): def __init__(self): super().__init__() print("Dog created") ``` 我们将祖先类放在子孙类名称之后的圆括号中。 如果派生类提供了自己的`__init__()`方法,并且我们想调用父构造器,则必须借助`super`函数显式调用基类`__init__()`方法。 ```py $ ./inherit.py Animal created Dog created Dog Eating Woof! ``` ## Python 多态 多态是对不同的数据输入以不同方式使用运算符或函数的过程。 实际上,多态意味着如果类 B 从类 A 继承,则不必继承关于类 A 的所有内容; 它可以完成 A 类所做的某些事情。 `basic_polymorphism.py` ```py #!/usr/bin/env python # basic_polymorphism.py a = "alfa" b = (1, 2, 3, 4) c = ['o', 'm', 'e', 'g', 'a'] print(a[2]) print(b[1]) print(c[3]) ``` Python 在内置类型中广泛使用了多态。 在这里,我们对三种不同的数据类型使用相同的索引运算符。 ```py $ ./basic_polymorphism.py f 2 g ``` 多态在处理继承时最常用。 `polymorphism.py` ```py #!/usr/bin/env python # polymorphism.py class Animal: def __init__(self, name=''): self.name = name def talk(self): pass class Cat(Animal): def talk(self): print("Meow!") class Dog(Animal): def talk(self): print("Woof!") a = Animal() a.talk() c = Cat("Missy") c.talk() d = Dog("Rocky") d.talk() ``` 在这里,我们有两种:狗和猫。 两者都是动物。 `Dog`类和`Cat`类继承了`Animal`类。 它们具有`talk()`方法,可以为它们提供不同的输出。 ```py $ ./polymorphism.py Meow! Woof! ``` ## Python 特殊方法 Python 编程语言中的类可以使用特殊的方法名称来实现某些操作。 这些方法不是直接调用,而是通过特定的语言语法调用。 这类似于在 C++ 或 Ruby 中所谓的运算符重载。 `special_methods.py` ```py #!/usr/bin/env python # special_methods.py class Book: def __init__(self, title, author, pages): print("A book is created") self.title = title self.author = author self.pages = pages def __str__(self): return "Title:{0} , author:{1}, pages:{2} ".format( self.title, self.author, self.pages) def __len__(self): return self.pages def __del__(self): print("A book is destroyed") book = Book("Inside Steve's Brain", "Leander Kahney", 304) print(book) print(len(book)) del book ``` 在我们的代码示例中,我们有一个`book`类。 在这里,我们介绍四种特殊方法:`__init__()`,`__str__()`,`__len__()`和`__del__()`。 ```py book = Book("Inside Steve's Brain", "Leander Kahney", 304) ``` 在这里,我们称为`__init__()`方法。 该方法创建`Book`类的新实例。 ```py print(book) ``` `print`关键字调用`__str__()`方法。 此方法应返回对象的非正式字符串表示形式。 ```py print(len(book)) ``` `len()`函数调用`__len__()`方法。 就我们而言,我们打印书的页数。 ```py del book ``` `del`关键字删除一个对象。 它调用其`__del__()`方法。 在下一个示例中,我们实现一个向量类并演示对其的加法和减法运算。 `vector.py` ```py #!/usr/bin/env python # vector.py class Vector: def __init__(self, data): self.data = data def __str__(self): return repr(self.data) def __add__(self, other): data = [] for j in range(len(self.data)): data.append(self.data[j] + other.data[j]) return Vector(data) def __sub__(self, other): data = [] for j in range(len(self.data)): data.append(self.data[j] - other.data[j]) return Vector(data) x = Vector([1, 2, 3]) y = Vector([3, 0, 2]) print(x + y) print(y - x) ``` 该示例介绍了`__add__`和`__sub__`方法。 ```py def __add__(self, other): data = [] for j in range(len(self.data)): data.append(self.data[j] + other.data[j]) return Vector(data) ``` 在这里,我们实现向量的加法运算。 当我们使用`+`运算符添加两个`Vector`对象时,将调用`__add__()`方法。 在这里,我们将各个向量的每个成员相加。 ```py $ ./vector.py [4, 2, 5] [2, -2, -1] ``` 这是输出。 在 Python 教程的这一部分中,我们介绍了 Python 中的面向对象编程。