30 天 Python 学习 - 第 8 天 - OOP 基础知识
Python 是一门多范式语言。这词儿听起来真酷!我来自 JavaScript 的世界,所以知道这一点,因为 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 引入的原型函数上的语法糖)。所以在我的思维模型中,我假设性地将它们联系起来。
但要看到 OOP 在 Python 中的实际运行,就必须深入研究并编写一些代码。
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 中的一个关键字,表示对类实例的引用。它用于访问类的变量或属性。在我的认知模型中,我将其与 JavaScriptthis
关键字进行比较。
在Avenger类中,fight 是一个方法,它假设了 Avenger 在被要求战斗时会做什么。这里它只是打印一个表情符号,但它可以是任何动作。
以这个 Avenger 类为原型,我创建了一个 Spiderman 对象。同样,这个类也可以用来创建其他复仇者,但似乎每个人在被要求战斗时都会做同样的事情,这很不酷。
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
现在好多了。每个复仇者都有自己独特的技能!这只是该职业的极简框架,可以添加更多功能,让复仇者更加精妙。
__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 个玩家对象,然后使用函数找出最大目标并打印出来。
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
关键字。无需实例化类即可调用此方法。
class Calculator:
def __init__(self,type):
self.type = type
@staticmethod
def multiply(num1, num2):
return num1 * num2
# cls is just like self which needs to passed as 1st parameter
print(Calculator.multiply(3,5)) # 15
今天就到这里。我将详细讲解和探索面向对象编程的原理,并在理解这些概念的过程中进行一些练习。我的思维模型正在缓慢而稳步地发展,以便在接下来的时间里攻克更高级的主题。
希望你也觉得它很有趣。
我最近正在看这个 Python 创始人的问答视频,挺有意思的。也想分享一下 :)
继续编码。让我知道你的想法。
祝你一切顺利!
鏂囩珷鏉ユ簮锛�https://dev.to/arindamdawn/30-days-of-python-day-8-oop-basics-3cai