【python学习】类、对象与魔法方法

一、类与对象

这里不多说什么拗口的理论了,说点个人理解吧,希望能帮小白理解。

在我一开始接触编程时,就觉得明明函数就已经是一种很好的封装了,程序不就应该用函数一点点的编出来嘛。实在是想不来怎么会还有更高级的封装方式——对象呢。可以说当时是一种完全想不来的状态,根本就不知道它存在的意义,不知道有没有和我一样的小伙伴,请在评论区举手示意,O(∩_∩)O哈哈~

后来,随着学习的深入,这才明白了对象存在的意义。其实这一切在学习数据结构时就埋下了伏笔。大家还记得什么线性表、栈、队列、二叉树、图吗?我们在学习这些的时候,老师是不是告诉过我们,这些东西都可以用抽象数据类型来表示,大致就是先定义一个容器,再定义一系列与它们的性质相匹配的操作。

比如对于栈,就有push(x),pop(),top()
而对于线性表则显然不存在这些操作。

这样我们就想到,对于一种容器,总有与之相匹配的一系列操作。故而,我们就可以用一种抽象度更高的封装方式——将容器与由它专属的一系列操作封装在一起。在这个封装后的代码块内,有表征容器属性的量,也有相应的函数可以对容器进行操作。比如,定义一个栈后,我们就可以直接对该栈进行push(x),pop(),top()等操作,非常方便。相比于以前,我们现在把操作和对象绑定到一起了。

哦,对了,忘了解释,容器就按字面意思理解就可以了,就是一种装数据的装置,比如数组就是最基本、最简单的一种容器。

说到这里,如果你还不能理解这样做(面向对象)的好处究竟在哪的话,且看下面这个更直观的例子:

在现实世界中存在人这个对象,因此我们可以定义人这个类,而人能做什么呢,能吃、能睡、能学习。。。那么就可以定义如下:

class:
	def 初始化(self, 姓名, 年龄,身高,饭量):
		self.姓名 = 姓名
		self.年龄 = 年龄
		self.身高 = 身高
		self.饭量 = 饭量
	def 吃饭(self):
		吃饭…
	def 睡觉(self):
		睡觉…
	def 学习(self):
		学习…	

以后在程序里就可以直接使用这个人,并让他干相应的事,比如:

工具人 =(x, y, z, h)	#x, y, z, h分别代表姓名、年龄、身高、饭量
工具人.吃饭()
工具人.睡觉()
工具人.学习()

更为方便的是,以后我们可以很方便的对人这个对象进行概念上的扩充。比如人分为男人和女人,男人和女人除了能吃饭、睡觉和学习外,还能XXOO(gkd~)。这样我们就可以创建两个新类,并从原有的类——人上继承所有属性和操作,并扩充新的、特有的属性。

class Male():	#注意这里的两个知识点:1.python中约定类名首字母大写。 
				#2.继承时,在类名后加括号写上父类名,表示继承
	def XX(self, XX的对象):
		与XX的对象XXOO…

class Female():	#人的其他属性全部继承
	def OO(self, OO的对象):
		与OO的对象XXOO…

# 下面开始使用

工具人 = Male(x, y, z, h)	#x, y, z, h分别代表姓名、年龄、身高、饭量
工具人.吃饭()
工具人.睡觉()
工具人.学习()
工具人.XX()

现在感受到类的方便之处了嘛?下面我们说说具体的定义,弄明白对象和类的关系内涵。

所谓对象就是一类具体实物经抽象后形成的实例,比如上例中的人、男人、女人,他们都是对象,是程序的基本单元。他们具有自己的属性和一系列具体的方法(或者说是操作)。故而我们常说
对象 = 属性 + 方法

而类则是对象的模板,封装了对应的现实实体的性质和行为。直观的表现为上面的那一段class后面缩进的代码
对象则是类的具体化,是用类这个模板造出的产品。

练习题

1、尝试执行以下代码,并解释错误原因:

class C:
    def myFun():
        print('Hello!')
    c = C()
    c.myFun()

程序执行后报错:NameError: name 'C' is not defined
原因分析:对类的调用放在了类定义里面,通俗的说就是说犯了禁止套娃(误。。。)的错误。此外,类里面的函数myFun()在定义时,应将self作为参数传入。改正后的代码如下:

class C:
    def myFun(self):
        print('Hello!')
c = C()
c.myFun()
output:
Hello!

2、按照以下要求定义一个游乐园门票的类,并尝试计算2个成人+1个小孩平日票价。

要求:

  • 平日票价100元
  • 周末票价为平日的120%
  • 儿童票半价

写的有点繁,见谅!这里不难想象,传入类中的信息应该是一个三元组,即要体现(是平日还是周末,是大人还是小孩,有多少人),具体见下:

class ticket:    
    def __init__(self):
        self.total = 0
        self.info = {"星期%d" % (i, ):{"儿童":0, "大人":0} for i in range(1,8)}
    def add_people(self, day, people, num):
        self.info["星期%d" % (day, )][people] += num
    def sub_people(self, day, people, num):
        self.info["星期%d" % (day, )][people] -= num
    def result(self):
        self.total = 0
        for i in self.info:            
            if i in ["星期6", "星期7"]:
                for j in self.info[i]:                    
                    if j == "儿童":                        
                        self.total += 60 * self.info[i][j]
                    else:                        
                        self.total += 120 * self.info[i][j]                    
            else:                
                for j in self.info[i]:                    
                    if j == "儿童":                        
                        self.total += 50 * self.info[i][j]
                    else:                        
                        self.total += 100 * self.info[i][j]                    
        return self.total

t = ticket()
t.add_people(1,"大人", 2)
t.add_people(1,"儿童", 1)
print(t.result())
output:
250

二、魔法方法

插句题外话,有没有和我一样总把魔法方法看成魔方方法的小伙伴o(╥﹏╥)o,有的话麻烦在评论区留个言,我们一起报团取暖,么么哒~

练习题

1、上面提到了许多魔法方法,如__new__,__init__, __str__,__repr__,__getitem__,__setitem__等等,请总结它们各自的使用方法。

请读者自行总结(危。。。)

2、利用python做一个简单的定时器类

要求:

  • 定制一个计时器的类。
  • start和stop方法代表启动计时和停止计时。
  • 假设计时器对象t1,print(t1)和直接调用t1均显示结果。
  • 当计时器未启动或已经停止计时时,调用stop方法会给予温馨的提示。
  • 两个计时器对象可以进行相加:t1+t2。
  • 只能使用提供的有限资源完成。
未完待续(危。。。)
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值