内容概要:
- isinstance()方法
- dir方法
- 封装
- eq与str方法
- 类属性和类方法
- 静态方法
一.isinstance()方法
作用: 判断变量是何种数据类型
num = 10
r1 = isinstance(num, int)
print(r1)
num_list = [10, 20, 30, 40]
r2 = isinstance(num_list, list)
print(r2)
num_tuple = (10, 20, 30)
r3 = isinstance(num_tuple, tuple)
print(r3)
num_dict = {'王泓鸡': 60, '阿伟': 70, '日含': 80}
r4 = isinstance(num_dict, dictionary)
print(r4)
适用场景: 需要限制输入的数据类型时,结合if 进行条件判断
二.dir()方法
作用: 查看对象内所有属性和方法包括所有内置与用户自定义的
str = 'hello world'
print(dir(str))
运行得到:
数据和行为带有__ (双下划线)开头的说明:这是私有的数据和行为,外部使用者不能直接调用(继承该类后可以使用)
三.封装
1.封装性 : 封装性是面向对象重要的基本特性之一, 封装隐藏了对象的内部细节, 只保留有限的对外接口, 外部调用者不用关心对象的内部细节, 使得操作对象变得简单.
例如: 一台计算机内部极其复杂, 有主板, CPU, 硬盘和内存等, 而一般人不需要了解它的内部细节, 计算机制造商用机箱把计算机封装起来, 对外提供了一些接口, 如鼠标, 键盘和显示器等, 使用计算机就变得非常简单.
2.属性封装的概念 : 将成员属性进行私有化,提供公共的访问方法,这个过程就是 属性的封装
。
私有变量 : 为了防止外部调用者随意存取类的内部数据 (成员变量), 内部数据 (成员变量) 会被封装为 私有变量
, 外部调用者只能通过方法调用私有变量.
在默认情况下, Python 中的变量是公有的, 可以在类的外部访问他们. 如果想让它们成为私有变量, 则在变量前加上双下划线 __ 即可.
使用属性 : 为了实现对象的封装, 在一个类中不应该有公有的成员变量, 这些成员变量应该
被设计为私有的, 然后通过公有的 set(赋值) 和 get(取值) 方法访问.
使用 set 和 get 方法进行封装
#定义一个类
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
@property #将name age 私有化
def name(self):
return self.__name
@name.setter #对传入的数据进行条件限制
def name(self, name):
if isinstance(name, str) and len(name) >= 2 and name not in ['王泓鸡', '伟哥', '日含']:
self.__name = name
else:
self.__name = '无名'
def run(self):
print(f'我叫{self.name},我今年{self.age}岁了')
@property
def age(self):
return self.__age
@age.setter
def age(self, age):
if isinstance(age, int) and 0 < age < 60: # isinstance 作用在这里体现出来了
self.__age = age
else:
self.__age = -1
if __name__ == '__main__':
stu1 = Student('王泓鸡', 88)
stu1.run()
四.eq与str方法
1.方法由来
要介绍这个方法,是因为有这方面的需求
# 回到最初的这段代码
class Student:
def __init__(self, name, age, gender)
self.name = name
if 1 < age < 18: #在这里进行条件判断
self.age = age
else:
pass
self.gender = gender
def run(self):
print(f'大家好,我叫{self.name},我今年{self.age}岁了,性别:{self.gender},爱好女')
stu1 = Student('网红鸡', 18, '下头男')
stu2 = Student('伟哥', 18, '中性')
#-------------------------------------------------------------------------------------------
#其实在定义类的时候省略了一个东西,写完整是这样子的
class Student(object):
# object为根类,如果一个类没有显示继承任何类,则其默认继承object类
查看object类的行为和属性:
print(dir(object))
从中可以找到我们要介绍的 ‘__ eq __ ’ 和’__ str __’
因此,eq方法和str方法均为 object类的方法
那么,还是那段 Student 类代码,我未表示他继承何类,则Student默认继承object类,也就拥有 eq方法和 str方法
2.eq方法的作用和使用
需求: 判断两个实例对象的数据是否相同
错误方法:
class Student:
def __init__(self, name, age, gender)
self.name = name
if 1 < age < 18: #在这里进行条件判断
self.age = age
else:
self.age = -1
self.gender = gender
def run(self):
print(f'大家好,我叫{self.name},我今年{self.age}岁了,性别:{self.gender},爱好女')
if __name__ == '__main__':
stu1 = Student('网红鸡', 18, '下头男')
stu2 = Student('伟哥', 18, '中性')
result = stu1 == stu2
print(result)
输出结果肯定为False!!!
这是因为对象的本质是一段地址,每创建一个对象都会在堆区占用一块内存来存储对象数据并返回对象地址,不同对象的地址肯定不同
正确方法: eq方法的使用
# 在设计类时,重写eq方法
class Student:
def __init__(self, name, age, gender)
self.name = name
if 1 < age < 18: #在这里进行条件判断
self.age = age
else:
self.age = -1
self.gender = gender
def run(self):
print(f'大家好,我叫{self.name},我今年{self.age}岁了,性别:{self.gender},爱好女')
#-------------------------------------------------------------------------------------------
def __eq__(self, other): #在main函数执行至 result = stu1 == stu2 时,自动调用该方法
# self -> stu1 other -> stu2
# self 就是实例对象,而stu2 可以为其他 例如: stu2 = 666
#所以需要对 stu2 类型进行限制
if isinstance(stu2, Student): # 如果stu2 为Student类
if self.name == other.name and self.age == other.age and self.gender == other.gender
return True
else:
return False
else:
return False
3.str方法
str方法的作用: 查看对象数据
前情回顾:
下面代码通过run() 方法查看对象数据,但是查看时需要定义该方法,不规范,不方便
因此我们使用该类固有的查看对象数据的方法
class Student:
def __init__(self, name, age, gender)
self.name = name
if 1 < age < 18: #在这里进行条件判断
self.age = age
else:
self.age = -1
self.gender = gender
def run(self):
print(f'大家好,我叫{self.name},我今年{self.age}岁了,性别:{self.gender},爱好女')
使用str方法:
class Student:
def __init__(self, name, age, gender)
self.name = name
if 1 < age < 18: #在这里进行条件判断
self.age = age
else:
self.age = -1
self.gender = gender
# 使用该方法需要在定义类时重写str方法
def __str__(self):
return f'Student [name = {self.name}, age = {self.age}, gender = {self.gender}]'
if __name__ == '__main__':
print(f'stu1 = {stu1}') # 运行到这里时会自动调用str方法,输出str方法的返回值
五.类属性和类方法
先不对’类属性’和’类方法’解释,通过具体的例子来理解
需求:
- 创建一个Calculator对象并定义两个属性: price 和 color
- 在Calculator类中定义一个方法 :get_sum() 实现求和功能
代码如下:
class Calculator():
def __init__(self, price, color):
self.price = price
self.color = color
def get_sum(self, *args):
sum = 0
for i in args:
sum += i
print(sum)
if __name__ == '__main__':
cal1 = Calculator(8, '黑色')
cal1.get_sum(10, 20)
写完后总觉得怪怪的…
get_sum(self, *args) 有self,表明是对象行为,而这个求和的方法与对象没有啥关系…
从内存角度:
运行到get_sum() 时,该函数入栈, 然后去堆区寻找对象数据,再通过对象来执行该行为
相比直接定义个求和函数,走对象行为来求和就绕了一圈
因此:
!!!类方法 !!!
通过类方法可以直接执行该功能
class Calculator():
def __init__(self, price, color):
self.price = price
self.color = color
@classmethod # 声明类方法
def get_sum(cls, *args): #注意这里self 变为cls了
sum = 0
for i in args:
sum += i
print(sum)
if __name__ == '__main__':
cal1 = Calculator(8, '黑色')
cal1.get_sum(10, 20)
再看下一个案例来理解 ‘类属性’
需求:
- 定义一个 Circle 类, 该类具备一个获取圆面积的行为
# 传入半径 radius 输出面积area
class Circle:
Pi = 3.14 # 这就是 类属性 过多的文字解释不如看一下代码
def __init__(self, radius):
self.radius = radius
def area(self):
return Circle.Pi * self.radius ** 2 # 类属性在使用时要在标识符前加类名
if __name__ == '__main__':
c1 = Circle(4)
result = c1.area()
print(result)
类属性和类行为的数据都保存在代码区(code_zone)中
六. 静态方法
特点:不需要访问对象和类的数据
自己跟自己玩
class Game:
@staticmethod #静态修饰符,该方法中没有默认参数
def show_menu(game_name):
print(f'''
{game_name}
1.开始游戏
2.结束游戏
3.暂停游戏
''')
if __name__ == '__main__':
Game.show_menu('鸡哥大战伟哥')
非常感谢你阅读到这里,如果这篇文章对你有帮助,希望能留下你的点赞👍 关注❤️ 分享👥 留言💬thanks!!!
感谢鸡哥、伟哥友情出演