# First_class_codes **Repository Path**: guibao2/first_class_codes ## Basic Information - **Project Name**: First_class_codes - **Description**: 此仓库用于托管北京工业大学机器人工程专业机器人综合实践课程第一讲的部分代码。 - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2023-02-21 - **Last Updated**: 2025-03-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README python面向对象教程 ================= 本教程用于演示基于python语言的面向对象算法 ---------------------------------------- 注:可以配合本文档中的代码,在[菜鸟工具](https://c.runoob.com/compile/9/)中进行python在线编辑与测试 # 1 面向对象概念 * 把数据及对数据的操作方法放在一起,作为一个相互依存的整体——对象。对同类对象抽象出其共性,形成类。类中的大多数数据,只能用本类的方法进行处理。类通过一个简单的外部接口与外界发生关系,对象与对象之间通过消息进行通信。程序流程由用户在使用中决定。对象即为人对各种具体物体抽象后的一个概念,人们每天都要接触各种各样的对象,如手机就是一个对象。 # 2 面向对象技术简介 ## 2.1 类之中所包含的内容 * 如果你以前没有接触过面向对象的编程语言,那你可能需要先了解一些面向对象语言的一些基本特征,在头脑里头形成一个基本的面向对象的概念,这样有助于你更容易的学习Python的面向对象编程。接下来我们先来简单的了解下面向对象的一些基本特征。 > 1. 类(class):用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。 > 2. 方法:类中定义的函数。 > 3. 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。 > 4. 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。 > 5. 实例化:创建一个类的实例,类的具体对象。 > 6. 实例变量:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,实例变量就是一个用 self 修饰的变量。 > 7. 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。 * 举例——类对象: ```python #!/usr/bin/python3 class MyClass: """一个简单的类实例""" i = 12345 def f(self): return 'hello world' # 实例化类 x = MyClass() # 访问类的属性和方法 print("MyClass 类的属性 i 为:", x.i) print("MyClass 类的方法 f 输出为:", x.f()) ``` 以上创建了一个新的类实例并将该对象赋给局部变量 x,x 为空的对象。 执行以上程序输出结果为: ```python MyClass 类的属性 i 为: 12345 MyClass 类的方法 f 输出为: hello world ``` ## 2.2 构造方法 * 类有一个名为`__init__()`的特殊方法(构造方法),该方法在类实例化时会自动调用,像下面这样: ```python class MyClass: def __init__(self): self.data = [] ``` 类定义了`__init__()`方法,类的实例化操作会自动调用`__init__()`方法。如下实例化类`MyClass`,对应的`__init__()`方法就会被调用: ```python x = MyClass() ``` 当然,`__init__()`方法可以有参数,参数通过`__init__()`传递到类的实例化操作上。例如: ```python #!/usr/bin/python3 class Complex: def __init__(self, realpart, imagpart): self.r = realpart self.i = imagpart x = Complex(3.0, -4.5) print(x.r, x.i) ``` 输出结果: `3.0 -4.5` ## 2.3 类方法 * 在类的内部,使用`def`关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数`self`, 且为第一个参数,self 代表的是类的实例。 * 举例——类方法: ```python #!/usr/bin/python3 #类定义 class people: #定义基本属性 name = '' age = 0 #定义私有属性,私有属性在类外部无法直接进行访问 __weight = 0 #定义构造方法 def __init__(self,n,a,w): self.name = n self.age = a self.__weight = w def speak(self): print("%s 说: 我 %d 岁。" %(self.name,self.age)) # 实例化类 p = people('runoob',10,30) p.speak() ``` 执行以上程序输出结果为: `runoob 说: 我 10 岁。` # 3 面向对象进阶 ## 3.1 数据封装 * 面向对象编程的一个重要特点就是数据封装。 举例如下: ```python #!/usr/bin/python3 class Student(): def __init__(self, name, score): self.name = name self.score = score def print_score(self): print('%s: %s' % (self.name, self.score)) bart = Student('Bart Simpson', 59) bart.print_score() ``` 其结果如下: `Bart Simpson: 59` * 这样一来,从外部看`Student`类,就只需要知道,创建实例需要给出`name`和`score`,而如何打印,都是在`Student`类的内部定义的,这些数据和逻辑被“封装”起来了,调用时不用知道内部实现的细节。 * 如果需要从外部获取部分内部变量的信息可以通过添加类方法的方式进行调用: ```python #!/usr/bin/python3 class Student(object): def __init__(self, name, score): self.name = name self.score = score def print_score(self): print('%s: %s' % (self.name, self.score)) def get_grade(self): if self.score >= 90: return 'A' elif self.score >= 60: return 'B' else: return 'C' ``` ## 3.2 继承和多态 * 在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑。可以在类内部的属性名称前面加`__`这个私有变量只可以在类内进行调用,无法从外部“获取到”,概念类似于c语言中的结构体中`private`概念。 * 比如,已经编写了一个名为`Animal`的`class`,有一个`run()`方法可以直接打印: ```python #!/usr/bin/python3 class Animal(object): def run(self): print('Animal is running...') ``` * 当我们需要编写`Dog`和`Cat`类时,就可以直接从`Animal`类继承: ```python #!/usr/bin/python3 class Animal(object): def run(self): print('Animal is running...') class Dog(Animal): pass class Cat(Animal): pass dog = Dog() cat = Cat() ``` * 对于`Dog`来说,`Animal`就是它的父类,对于`Animal`来说,`Dog`就是它的子类。`Cat`和`Dog`类似。 * 继承最大的好处是子类获得了父类的全部功能。由于`Animial`实现了`run()`方法,因此,`Dog`和`Cat`作为它的子类,什么事也没干,就自动拥有了`run()`方法: ```python dog.run() cat.run() ``` 运行结果为: `Animal is running...` `Animal is running...` * 除此之外,我们也可以对子类添加他们自己的方法,例如在`dog`中: ```python #!/usr/bin/python3 class Animal(object): def run(self): print('Animal is running...') class Dog(Animal): def run(self): print('Dog is running...') def eat(self): print('Eating meat...') ``` * 当子类和父类都存在相同的`run()`方法时,我们说,子类的`run()`覆盖了父类的`run()`,在代码运行的时候,总是会调用子类的`run()`。这就是继承的另一个好处:多态。 ```python #!/usr/bin/python3 class Animal(object): def run(self): print('Animal is running...') class Dog(Animal): def run(self): print('Dog is running...') class Cat(Animal): def run(self): print('Cat is running...') def run_twice(animal): animal.run() animal.run() run_twice(Animal()) run_twice(Dog()) run_twice(Cat()) ``` 运行结果为: ```python Animal is running... Animal is running... Dog is running... Dog is running... Cat is running... Cat is running... ``` * 当需要传入Dog、Cat……时,只需要接收Animal类型就可以了,然后,按照Animal类型进行操作即可。多态真正的威力:调用方只管调用,不管细节,而当新增一种Animal的子类时,只要确保run()方法编写正确,不用管原来的代码是如何调用的。这就是著名的==“开闭”原则==: > 对扩展开放:允许新增Animal子类; > 对修改封闭:不需要修改依赖Animal类型的run_twice()等函数。 * 继承还可以一级一级地继承下来,就好比从爷爷到爸爸、再到儿子这样的关系。而任何类,最终都可以追溯到根类object,这些继承关系看上去就像一颗倒着的树。 ## 3.3 其他类方法 > `__init__ `: 构造函数,在生成对象时调用 > `__del__` : 析构函数,释放对象时使用 > `__repr__` : 打印,转换 > `__setitem__` : 按照索引赋值 > `__getitem__`: 按照索引获取值 > `__len__`: 获得长度 > `__cmp__`: 比较运算 > `__call__`: 函数调用 > `__add__`: 加运算 > `__sub__`: 减运算 > `__mul__`: 乘运算 > `__truediv__`: 除运算 > `__mod__`: 求余运算 > `__pow__`: 乘方 [参考]: https://www.runoob.com/python3/python3-tutorial.html https://blog.csdn.net/strivequeen/article/details/113665563