Python 30 天 – 第 8 天 – OOP 基础知识

- Python 30 天 – 第一天 – 简介
- Python 30 天 – 第 2 天 – 数据类型 I
- Python 30 天 – 第 3 天 – 数据类型 II
- Python 30 天 – 第 4 天 – 数据类型 III
- Python 30 天 – 第 5 天 – 条件和循环 I
- Python 30 天 – 第 6 天 – 循环 II 和函数
- Python 30 天 – 第 7 天 – 开发者环境
通过JavaScript我意识到,Python 是一种多范式编程语言,因为 JavaScript 也是一种多范式语言。
这意味着有不止一种明确的方式来思考我们如何用 Python 编写我们的代码,以及如何构建我们的代码。在现实世界中,在处理现实项目时,我们试图通过编程解决的问题很复杂,甚至在编写一行代码之前就需要进行大量的头脑风暴。优秀的程序员不仅要考虑如何用代码解决问题,还要考虑如何编写更易于维护、在必要时更易于扩展、也更易于阅读和编写的代码。这种结构化和组织代码的方式被称为编程范式。它就像一个带有一些预定义规则集的模式,开发人员可以遵循这些规则来避免混乱。想象一下,如果每个开发人员都试图精明并以他们独特的方式编写代码。没有明确的模式,项目就注定要失败!
回到 Python!
在 Python 中,一切都是对象。我探索的数据类型都是对象,它们都有自己的关联属性和方法来执行某些操作。这些对象作为实例来自它们的类。这意味着 Python 中的所有数据类型都有一个已定义的结构或原型,其中所有属性和功能的细节都已定义。
print(type(2)) # <class 'int'>
print(type(2.5)) # <class 'float'>
print(type('Python')) # <class 'str'>
print(type(True)) # <class 'bool'>
print(type({})) # <class 'dict'>
print(type([])) # <class 'list'>
print(type(())) # <class 'tuple'>
print(type(None)) # <class 'NoneType'>
就像内置类一样,可以创建自定义类来表示现实世界的事物,如汽车、机器、人类、动物或任何东西。这种在代码中将现实世界的实体及其属性和行为表示为类的这种表示可以被认为是面向对象编程范式的松散定义。然后可以使用每个类来创建对象的实例。这些对象可以与其他对象组合以模拟现实世界的功能。
在 JavaScript 世界中,也可以创建自定义类(尽管 JS 中的类更多是 ES6 引入的原型函数之上的语法糖)。所以在我的心智模型中,我假设将它们联系起来。
但是要在 Python 中看到 OOP 的运行情况,必须深入研究并编写一些代码。
class Avenger: def __init__(self, name): self.name = name def fight(self): print('?') spiderman = Avenger('Spiderman') print(type(Avenger)) # <class 'type'>
print(type(spiderman)) # <class '__main__.Avenger'> --> instance of Avenger
在 Python 中,类的命名约定是驼峰命名和单数命名,与需要蛇形命名的变量不同。
__init__ 是一个初始化方法(也称为构造函数方法)。它用于初始化类的变量。在上面的类中, name 正在被初始化。例如,在 JavaScript 中,这在类的构造函数中是类似的。
self 是 Python 中的一个关键字,它是对类实例的引用。它用于访问类的变量或属性。在我的心智模型中,我将其与 JavaScript 中的 this 关键字进行了比较。
在 Avenger 类中,fight 是一种方法,它是Avenger 在被要求fight 时会做什么的假设表示。在这里它只是打印一个表情符号,但它可以是任何动作。使用这个 Avenger 类作为原型,我创建了一个Spiderman 对象。同样,这个类可以用来创造其他avengers
class Avenger: def __init__(self, name, weapon): self.name = name self.weapon = weapon def fight(self): print(self.weapon) spiderman = Avenger('Spiderman', 'dispatch a web')
thor = Avenger('Thor', 'thunder attack') spiderman.fight() # dispatch a web
thor.fight() # thunder attack
现在好多了。每个avenger 都有独特的表现!这是该类的最小框架,它可以填充许多功能,使avengers更复杂。
每次实例化(创建)对象时,都会调用被称为构造函数方法的 __init_。它也提供了很多控制机制,只允许在满足条件时创建对象或为参数添加默认值。
class MotorBike: def __init__(self, brand, age): if(age <= 15): self.brand = brand self.age = age def start(self): print(f'starting {self.brand}....') bullet = MotorBike('Royal Enfield Bullet',20)
bullet.start() # error. object is created only if age is less than or equals 15
编码练习
任务是创建一个具有名称和目标属性的类SoccerPlayer,然后创建 3 个player 对象,然后使用函数找出最大目标并打印出来。
class SoccerPlayer: def __init__(self, name, goals): self.name = name self.goals = goals def calculateMaxGoals(*args): print(args) return max(*args) messi = SoccerPlayer('messi', 10)
ronaldo = SoccerPlayer('ronaldo',22)
neymar = SoccerPlayer('neymar', 8) max_goals = calculateMaxGoals(messi.goals, ronaldo.goals, neymar.goals)
print(f'The highest number of goals is {max_goals} goals')
@classmethod 和 @staticmethod
方法可以附加到类而不创建它的实例。有两种方法可以这样做。
@classmethod 允许通过在方法名称之上添加所谓的装饰器@classmethod 来在类中创建方法。稍后我将详细探讨装饰器,但现在只是大致了解创建类方法的概念。
class Calculator:
def __init__(self, type):
self.type = type
@classmethod
def calculate_sum(cls, num1, num2):
return num1 + num2 # cls is just like self which needs to passed as 1st parameter
print(Calculator.calculate_sum(3, 5)) # 8
@staticmethod 与@classmethod 非常相似。它只是不需要传递 cls 关键字。可以在不实例化类的情况下调用此方法。
常见问题FAQ
- 程序仅供学习研究,请勿用于非法用途,不得违反国家法律,否则后果自负,一切法律责任与本站无关。
- 请仔细阅读以上条款再购买,拍下即代表同意条款并遵守约定,谢谢大家支持理解!