目录
前言
- python中一切皆为对象,类型的本质就是类,所以,不管你信不信,你已经使用了很长时间的类了。
dict # 类型dict就是类dict
# <class 'dict'>
d = dict(name='Hello World') # 实例化
d.pop('name') # 向d发一条消息,执行d的方法pop
# 'Hello World'
-
从上面的例子来看,字典就是一类数据结构,我一说字典你就知道是那个用{}表示,里面由k-v键值对的东西,它还具有一些增删改查的方法。但是我一说字典你能知道字典里具体存了哪些内容么?不能,所以我们说对于一个类来说,它具有相同的特征属性和方法。
-
而具体的{‘name’: ‘Hello World’}这个字典,它是一个字典,可以使用字典的所有方法,并且里面有了具体的值,它就是字典的一个对象。对象就是已经实实在在存在的某一个具体的个体。
-
再举一个其他的例子,通俗一点,比如你现在有一个动物园,你想描述这个动物园,那么动物园里的每一种动物就是一个类,老虎、天鹅、鳄鱼、熊。他们都有相同的属性,比如身高体重出生时间和品种,还有各种动作,比如鳄鱼会游泳,天鹅会飞,老虎会跑,熊会吃。
-
但是这些老虎熊啥的都不是具体的某一只,而是一类动物。虽然他们都有身高体重,但是你却没有办法确定这个值是多少。如果这个时候给你一只具体的老虎,而你还没死,那你就能给他量量身高称称体重,这些数值是不是就变成具体的了?那么具体的这一只老虎就是一个具体的实例,也是一个对象。不止这一只,其实每一只具体的老虎都有自己的身高体重,那么每一只老虎都是老虎类的一个对象。
-
在python中,用变量表示特征,用函数表示技能,因而具有相同特征和技能的一类事物就是‘类’,对象是则是这一类事物中具体的一个。
阶段一:对“类”的理解
一.理解创建类的基本方法
- 类是一种面向对象计算机变成语言的构造,是创建对象的蓝图,描述了所创建的对象共同的属性和方法。
- 举个简单的例子(超级英雄的类):
class SuperMan: # class:定义类的关键词 SuperMan:类的名称(必须使用“驼峰命名法”)
''' # 类的文档
A class of superman
'''
def __init__(self, name, gender): # 初始化方法
self.name = name # 名字
self.gender = gender # 性别
self.single = False # 都不是单身
self.illness = False # 身体倍儿棒
def sunflower_bible(self): # 普通方法(和函数的形式很像,不过在类中,我们管它叫‘方法’)
return 'There is no trick, but there must be a trick!'
superman = SuperMan(name = 'Invincible-Eastern', gender = 'male') # 实例化
pithy_formula = superman.sunflower_bible() # 调用方法
print(superman.name)
print(superman.single)
print(pithy_formula)
# Invincible-Eastern
# False
# There is no trick, but there must be a trick!
- 至于‘self’、‘__init__’具体指什么呢?我们在此处先不做过多说明,先有个印象就好啦
二.初步理解对象和面向对象
- 对象:表示客观世界问题空间中某个元素具体事物,又表示软件系统解空间中的基本元素。
- 面向对象程序设计:是一种程序设计范型,也是一种程序开发的方法。
- 举个例子:用类写一个判断输入的年月日是否合理。
class Date:
def __init__(self, year, month, day): # 将年、月、日传入
self.year = year
self.month = month
self.day = day
def estimate_y(self): # 判断年是否正确的方法
if self.year >= 0: # 必须大于0
print('{}年:年正确'.format(self.year))
return True
else:
print('{}年:年错误(年份应大于0!)'.format(self.year))
def estimate_year(self): # 是否是闰年
if (self.year % 4 == 0 and self.year % 100 != 0) or self.year % 400 == 0:
return True
else:
return False
def estimate_month(self): # 判断月是否正确的方法
if 1 <= self.month <= 12: # 月份为1-12月
print('{}月:月正确'.format(self.month))
return True
else:
print('{}月:月有误(一年只有12个月!)'.format(self.month))
return False
def estimate_day(self): # 判断月份是有31天还是30天(28天还是29天)
if self.month == 1 or self.month == 3 or self.month == 5 or self.month == 7 or self.month == 8 or self.month == 10 or self.month == 12:
# 大月,应该有31天
if self.day > 31:
print('{}日:日错误({}月为大月,最多有31天)'.format(self.day, self.month))
return False
else:
print('{}日:日正确'.format(self.day))
return True
elif self.month == 4 or self.month == 6 or self.month == 9 or self.month == 11:
# 小月,应该有30天
if self.day > 30:
print('{}日:日错误({}月为小月,最多有30天)'.format(self.day, self.month))
return False
else:
print('{}日:日正确'.format(self.day))
return True
elif self.month == 2: # 2月单独判断:28天或29天(闰年有29天)
if self.estimate_year():
if self.day > 29:
print('{}日:日错误({}年是闰年,二月最多有29天)'.format(self.day, self.year))
return False
else:
print('{}日:日正确'.format(self.day))
return True
else:
if self.day > 28:
print('{}日:日错误({}年不是闰年,二月最多有28天)'.format(self.day, self.year))
return False
else:
print('{}日:日正确'.format(self.day))
return True
def estimate_all(self): # 判断年月日是否都正确
if self.estimate_y():
if self.estimate_month():
if self.estimate_day():
print('{}-{}-{}:全部正确!'.format(self.year, self.month, self.day))
string = input('请输入“xxxx xx xx”形式的日期(不需要0占位):')
date = Date(int(string.split()[0]), int(string.split()[1]), int(string.split()[2])) # 实例化
Date.estimate_all(date)
阶段二:self的概念、特殊方法的说明
一.self的概念
- self指的是类实例对象本身,相当于一个身份标志,表明是属于该类中的方法。self名称不是必须的,在python中self不是关键词,你可以定义成a或b或其它名字都可以,但是约定成俗(为了和其他编程语言统一,减少理解难度)最好用self。
class Stu():
name = '杨幂'
# who是类Stu中的方法,self可以理解为:表示Stu的方法
def who(self):
print("我是%s" %self.name)
stu = Stu
# 调用stu中的方法
stu.who(stu) # # 我是杨幂
二.特殊方法
1.定义:类中可以定义一些特殊方法也称为魔术方法,都是形如__xxx__()这种形式
2.常见的特殊方法:
- __init__():构造函数,用于类的初始化。
- 不需要调用,直接执行
- 方便传参和调用
class Stu():
# 初始化函数,并将实参传入
def __init__(self, name):
self.name = name
print('大家好!')
def who(self):
print("我是%s" %self.name)
# 将初始的参数传入类中
stu = Stu('杨幂')
# 调用stu中的方法
stu.who() # 我是杨幂
- __str__():本意是转换成字符串,但更多用于设置打印类的格式
class Stu():
# 初始化函数,并将实参传入
def __init__(self, name):
self.name = name
def who(self):
print("我是%s" %self.name)
stu = Stu('杨幂')
print(stu) # <__main__.Stu object at 0x000001E570724610>
- 使用str方法设置打印格式:
class Stu():
# 初始化函数,并将实参传入
def __init__(self, name):
self.name = name
# 设置打印格式
def __str__(self):
return '大家好,我是%s'%self.name
def who(self):
print("我是%s" %self.name)
stu = Stu('杨幂')
print(stu) # 大家好,我是杨幂
- 更多内容详情参考:【python】类的特殊方法
三.封装
- 出现封装的原因:我们需要一种方式来增强数据的安全性
- 属性不能随意修改
- 属性不能改为任意的值
- 我们用代码来举例:
class Stu():
# 初始化函数,并将实参传入
def __init__(self, name):
self.name = name
def who(self):
print("我是%s" %self.name)
stu = Stu('杨幂')
stu.who() # 我是杨幂
# 将name属性进行修改
stu.name = '陈赫'
stu.who() # 我是陈赫
- 我们可以看到:通过简单的赋值操作就可以将属性进行改动。若我们有些数据并不希望被修改,那么就要用到新的“命名”方法:__name
class Stu():
# 初始化函数,并将实参传入
def __init__(self, name):
self.__name = name
def who(self):
print("我是%s" %self.__name)
stu = Stu('杨幂')
stu.who() # 我是杨幂
# 将name属性进行修改
stu.name = '陈赫'
stu.who() # 我是杨幂
- 经过对命名的改动,我们发现并不能将类中的属性进行修改。而在外部的“陈赫”只是为类新增了一个name的属性。
- 那我们有办法修改“杨幂”吗?当然可以。只是我们只能在类的内部进行修改。简而言之,就是使用方法。
class Stu():
# 初始化函数,并将实参传入
def __init__(self, name):
self.__name = name
# 设置修改的方法
def setter(self, new_name):
self.__name = new_name
print('修改成功!')
def who(self):
print("我是%s" %self.__name)
stu = Stu('杨幂')
stu.who() # 我是杨幂
# 将name属性进行修改
stu.setter('陈赫')
stu.who() # 修改成功!\n我是陈赫
- 使用封装,确实增加了类的定义的复杂程度,但是它也确保了数据的安全