Python学习笔记——类和对象(如何定义一个类并创建对象、魔法方法、__init__、__repr__)
2021/10/23 22:11:17
本文主要是介绍Python学习笔记——类和对象(如何定义一个类并创建对象、魔法方法、__init__、__repr__),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
面向对象的编程语言?
Python到底是一种什么类型的编程语言:面向对象、函数式还是过程式语言?
Python借用了所有这3种流行方法的编程范式,还鼓励程序员根据需要混合使用。
在其他编程语言中(如Java)你写的所有代码都必须放在一个类里,要从这个类实例化对象
在Python中,可以用你熟悉的任何一种范式创建代码,可以同样把所有代码放在一个类中,也可以不这么做
Python支持面向对象编程(OOP):如封装一个对象、继承和多态
Python的类
- 类将行为(本质即函数)和状态(本质即变量)打包在一个对象中
- Python中的类相当于JS中的原型,类可以完成对象实例化(从类可以创建新的对象实例)
- 对象共享行为,但不共享状态
从一个类创建对象时,每个对象会共享这个类的行为(类中定义的方法),但是会维护其自己的状态副本(属性)
为类增加方法:直接在类中定义函数即可
为类增加属性:在__init__
中完成
定义一个类,并创建对象
定义一个
CountFromBy
类,从这个类能创建如下的对象:
- 属性:具有初始值
val
和步长incr
(若没有指定,默认val为0,incr为1)- 方法:具有
increase()
方法,每次调用时对象的属性val增加incr
1. 为类增加方法
- 要为类增加方法,直接在类中使用
def
定义函数即可 - 注意,Python类的任何方法,必须传入第一个参数,用来指示当前对象,即当前正在使用此方法的对象
Python编程社区约定的做法是:总是将方法的第一个参数命名为self
(类似于JS中的this
) - 在方法代码组中,引用属性时要加
self
前缀,确保操作应用于对象的属性。
如下,应该写self.val
而不是val
前面说过对象共享行为,但不共享状态,只有这样才知道在方法中要修改哪一个对象的属性(即当前正在使用方法的那个对象)
另外,这样做能保证调用结束后,变量仍存在:如果只写val
,则调用结束后变量被销毁,无法再访问val(超出作用域),而对象中的val属性没有发生改变
class CountFromBy:#约定:对于类,采用CamelCase命名 def increase(self) -> None: self.val += self.incr ... ...
如何调用方法
根据上文,已经知道Python对象调用方法时,第一个参数一定传入这个对象的引用
那么,对于CountFromBy类的a实例,我们调用increase方法时,应该这样写:
>>>a = CountFromBy(0,1) >>>CountFromBy.increase(a)#调用类的一个方法,传入的第一个参数是某个对象实例
然而实际的写法为
>>>a = CountFromBy(0,1) >>>a.increase()
实际上,解释器会自动将a.increase()
语句转化为CountFromBy.increase(a)
语句
因此我们只要使用a.increase()
的简单版本就好
- 这时要明白,我们调用
increase
方法时,需要提供的参数就少一个
因为在调用方法时,解释器自动将当前对象a
赋给第一个参数self
2. 从类创建对象实例时,初始化对象的属性
创建一个新对象时,如何初始化呢?
如果你了解面向对象编程,肯定会想到在其他语言中的“构造函数”。
构造函数是一个特殊方法,它定义了第一次创建一个对象时会发生什么(包括对象实例化和属性初始化)
在JS中使用构造函数:
//Dog称为构造函数 function Dog(name, breed, weight) { //“对象实例化”部分(将传入的参数赋给新对象的属性) this.name = name; this.breed = breed; this.weight = weight; } Dog.prototype.run = function() { console.log("Run!"); }; //“属性初始化”部分 Dog.prototype.name = "dog"; Dog.prototype.breed = "unknown"; Dog.prototype.weight= 0; //传入参数,获得一个具有某些属性的对象 var fido = new Dog("Fido", "Mixed", 38);
在 Python中有所不同:
- 对象实例化由解释器自动处理,所以不需要定义构造函数来完成这个工作
- 属性初始化的工作需要自己完成:有一个名为
__init__
(称为dunder init)的魔法方法允许你根据需要初始化属性。
绕路介绍一下前置知识:魔法方法__init__
(dunder init)
object
类是Python解释器内置的类- Python中所有类都自动继承这个类(包括你自定义的类)
这意味着,所有类都继承了object
类的标准行为(即一些方法),当然也可以根据需要覆盖它们(提供你自己的方法实现) object
中的标准方法中,若其名称包含双下划线dunder__
,称为魔法方法
在自己的类中,覆盖这些魔法方法(编写自己的代码)通常很有用
覆盖__eq__
方法,可指定从类创建的对象使用相等操作符==
时会发生什么
覆盖__ge__
方法,可指定对对象使用大于操作符>
时要发生什么
覆盖__init__
方法,可指定要如何初始化对象属性
覆盖__repr__
方法,可指定解释器要如何表示对象
使用__init__
初始化对象的属性
从 Python类创建的新对象,如何初始化呢?
在你的类中覆盖(重新定义)__init__
方法即可
- 每次从你的类创建一个新对象时,解释器都会调用你的
__init__
方法 - 传入类的参数值,会被发送到
__init__
中
例如,对于mycount=CountFromBy(100,10)
,100和10会被传入__init__
ps.__init__
同样是一个方法,也要遵循前述规则:必须有第一个参数self
class CountFromBy: def __init__(self,v: int=0, i: int=1) -> None: #v默认值为0,i默认值为1 self.val = v self.incr = i def increase(self) -> None: self.val += self.incr
3. 创建并使用对象
已经为类增加了方法、初始化了属性
下面就可以从类创建对象了
>>> a=CountFromBy()#使用默认值val=0,incr=1 >>> a.increase() >>> a.val 1 >>> b=CountFromBy(100,10)#指定属性val=100,incr=10 >>> b.increase() >>> b.val 110
额外介绍一个魔法方法:__repr__
直接打印“对象”,会显示什么呢?
>>> c=CountFromBy() >>> c <__main__.CountFromBy object at 0x000002BE66000A90> >>> type(c) <class '__main__.CountFromBy'> >>> hex(id(c)) '0x2be66000a90'
解释器默认表示对象的方式是:对象类型+内存地址
编写自己的魔法方法__repr__
,可以覆盖这种默认行为,并指定解释器对于对象的字符串表示
class CountFromBy: def __init__(self,v: int=0, i: int=1) -> None: self.val = v self.incr = i def increase(self) -> None: self.val += self.incr def __repr__(self) -> str: return str(self.val) ================= RESTART: C:\Users\13272\Desktop\CountFb.py ================= >>> c=CountFromBy(100,10) >>> c.val 100 >>> c 100#自定义的对象表示方法
这篇关于Python学习笔记——类和对象(如何定义一个类并创建对象、魔法方法、__init__、__repr__)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-26Python基础编程
- 2024-11-25Python编程基础:变量与类型
- 2024-11-25Python编程基础与实践
- 2024-11-24Python编程基础详解
- 2024-11-21Python编程基础教程
- 2024-11-20Python编程基础与实践
- 2024-11-20Python编程基础与高级应用
- 2024-11-19Python 基础编程教程
- 2024-11-19Python基础入门教程
- 2024-11-17在FastAPI项目中添加一个生产级别的数据库——本地环境搭建指南