Python学习笔记八

面向对象(object)编程

对象是指现实中的物体或实体
面向对象:把一切看成对象(实例),让对象和对象之间建立关联关系
对象的特征:对象有很多的属性(名词: 姓名,性别,年龄);
对象有很多行为(动词: 学习,吃饭,睡觉,看书)

类是拥有相同属性和行为的对象分为一组,即为一个类,类是用来描述对象的工具,用类可以创建同类对象。
车(类)-----------> BYD E6(京A.88888) 实例
车(类)-----------> BMW X5(京A.00000) 实例

狗(类)----------->小京巴(户籍号:000001)
----------->导盲犬(户籍号:000002)
int(类)----------->100(对象/实例)
----------->200(对象/实例)
类的创建语句:
语法:class 类名(继承列表):
‘’‘类的文档字符串’’’
实例方法定义(类内的函数称为方法method)
类变量定义
类方法定义
静态方法定义
作用:创建一个类
用于描述词类对象的行为和属性
类用于创建此类的一个或多个对象(实例)
示例:

# 此示例示意类的定义

class Dog:		# 定义一个类,类名为Dog
	pass

dog1 = Dog()		# 构造函数,创建Dog类的对象
print(id(dog1))		# 4378526216
dog2 = Dog()		# 创建Dog类的另一个对象
print(id(dog2))		# 4382983672

# 类似于如下语法:
int1 = int()
int2 = int()

类 对象 实例
class | object | instance

构造函数

表达式:
类名([创建传参列表])
作用:创建这个类的实例对象,并返回此实例对象的引用关系
实例(对象)说明:实例有自己的作用域和名字空间,可以为该实例添加实例变量(属性);实例可以调用类方法和实例方法;实例可以访问类变量和实例变量
示例:

class Dog:
	pass

dog1 = Dog()

实例方法:
语法:
class 类名(继承列表):
def 实例方法名(self, 参数1, 参数2, …):
‘’‘实例方法的文档字符串’’’
语句块
作用:用于描述一个对象的行为,让此类型的全部对象都拥有相同的行为
说明:实例方法实质是函数,是定义在类内的函数;
实例方法至少有一个形参,第一个形参代表调用这个方法的实例, 一般命名为’self’
实例方法的调用语法:
实例.实例方法名(调用参数)

类名.实例方法名(实例,调用传参)
示例:

# 此实例示意如何用实例方法(method)来描述Dog类的行为
class Dog:
	def eat(self, food):
		'''此方法用来描述小狗吃东西的行为'''
		print("小狗正在吃:", food)

	def sleep(self, hour):
		print("小狗睡了", hour, "小时")

# 创建一个Dog类的实例:
dog1 = Dog()
dog1.eat("狗粮")		# 小狗正在吃: 狗粮
dog1.sleep(10)		# 小狗睡了 10 小时
# dog1.play("球")		# 对象不能调用类内不存在的方法

# 创建另一个Dog对象
dog2 = Dog()
dog2.eat("骨头")
dog2.sleep(2)
# 可以用下面的方法调用方法
Dog.eat(dog2, '苹果')
属性(attribute)

属性也叫实例变量,每个实例都可以有自己的变量,此变量称为实例变量(也叫属性)
属性的使用语法:实例.属性名
赋值规则:首次为属性赋值则创建此属性;再次为属性赋值则改变属性的绑定关系
作用:用来记录对象自身的数据
实例:


# 此示例示意为对象添加属性

class Dog:
	pass

# 创建第一个对象
dog1 = Dog()
dog1.kinds = '京巴'		# 添加属性kinds
dog1.color = '白色'		# 添加属性color
dog1.color = '黄色'
print(dog1.color, '的', dog1.kinds)			# 访问属性

dog2 = Dog()
dog2.kinds = '牧羊犬'
dog2.color = '灰色'

实例方法和实例变量(属性)结合在一起使用:
示例:

class Dog:
	def eat(self, food):
		print(self.color, '的', self.kinds, '正在吃', food)

# 创建第一个对象
dog1 = Dog()
dog1.kinds = '京巴'		# 添加属性kinds
dog1.color = '白色'		# 添加属性color
dog1.color = '黄色'
#print(dog1.color, '的', dog1.kinds)			# 访问属性
dog1.eat('骨头')

dog2 = Dog()
dog2.kinds = '牧羊犬'
dog2.color = '灰色'
dog2.eat('包子')
class Student:
	def set_info(self, name, age=0):
		'''此方法用来给学生对象添加姓名和年龄属性'''
		self.name = name
		self.age = age
		return self.name, self.age

	def show_info(self):
		'''此处显示学生的信息'''
		print(self.name, '今年', self.age, '岁')

s1 = Student()
s1.set_info('xiaomaomao', 1)

s2 = Student()
s2.set_info('xiaoxiaomao', 1)

s1.show_info()
s2.show_info()
删除属性

用del语句可以删除一个对象的实例变量
语法:del 对象.实例变量名
示例:

class Cat:
	pass

cat1 = Cat()		# 创建对象
c1.color = '白色'		# 添加属性
print(c1.color)
del c1.color		# 删除属性
print(c1.color)		# 属性错误
初始化方法

作用:对新创建的对象添加实例变量(属性)或相应的资源
语法格式:class 类名(继承列表):
def init(self [, 形参列表])
语句块
说明:(1) 初始化方法名必须__init__不可改变;
(2) 初始化方法会在构造函数创建实例后自动调用,且实例自身通过第一个参数self传入__init__方法;
(3) 构造函数的实参将通过__init__方法的形参列表传入__init__方法中;
(4) 初始化方法内部如果需要返回则只能返回None
示例:

# 此示例示意__init__方法的自动调用及添加示例变量

class Car:
	def __init__(self, c, b, m):
		self.color = c 	# 颜色
		self.band = b   # 品牌
		self.model = m 	# 型号

	def run(self, speed):
		print(self.color, '的', self.band, self.model,
		 '正在以', speed, '公里/小时的速度行驶')

	def set_color(self, clr):
		'''此方法用来修改车的颜色信息'''
		self.color = clr


a4 = Car('红色', '奥迪', 'A4')	
a4.run(179)				# # 红色 的 奥迪 A4 正在以 179 公里/小时的速度行驶
#a4.color = '黑色'
a4.set_color('黑色')
a4.run(300)			# 黑色 的 奥迪 A4 正在以 300 公里/小时的速度行驶

t1 = Car('蓝色', 'TESLA', 'Modle S')
t1.run(299)			# 蓝色 的 TESLA Modle S 正在以 299 公里/小时的速度行驶


# a4.__init__('白色', 'Tesla', 'Model S')		# 显式调用__init__
析构方法

语法:
class 类名(继承列表):
del(self):
语句块
说明:析构方法在对象销毁时被自动调用
作用:清理此对象所占用的资源
示例:

# 此示例示意__del__方法的用法
class Car:
	def __init__(self, name):
		self.name = name
		print("汽车", name, "对象已经创建")

	def __del__(self):
		print(self.name, "对象已经销毁")


c1 = Car("BYD")		# 汽车 BYD 对象已经创建
c1 = Car("BMW")

python不建议在析构方法内做任何事情,因为对象销毁的时间难以确定。

预置实例属性

__dict__属性:此属性绑定一个存储此实例自身变量的字典
示例:

class Dog:
	pass

dog1 = Dog()	# 创建一个Dog类型的实例
print(dog1.__dict__)		# {}
dog1.kinds = '京巴'
print(dog1.__dict__)		# {'kinds': '京巴'}
dog1.color = '白色'
print(dog1.__dict__)		# {'kinds': '京巴', 'color': '白色'}
print(dog1.color)		# 白色

__class__属性: 此属性用来绑定创建此实例的类
作用:可以借助此属性来访问创建此实例的类
示例:

class Dog:
	pass

dog1 = Dog()
print(dog1.__class__)		# <class '__main__.Dog'>
dog2 = Dog()
dog3 = dog1.__class__()		# 等同于dog1 = Dog(),创建dog1的同类对象

下面示例示意如何用面向对象的方式创建对象,并建立对象与对象之间的逻辑关系

# 此示例示意如何用面向对象的方式创建对象,并建立对象与对象之间的逻辑关系

class Human:
	'''人类,用于描述人的行为'''
	def __init__(self, n, a):
		self.name = n 		# 姓名
		self.age = a 		# 年龄
		self.money = 0		# 钱数为0

	def teach(self, other, skill):
		print(self.name, "教", other.name, "学", skill)

	def works(self, money):
		self.money = self.money + money
		print(self.name, "工作赚了", self.money, "元钱")

	def borrow(self, other, money):
		if other.money > money:
			print(other.name, "借给", self.name, money, "元钱")
			self.money = self.money + money
			other.money = other.money - money
		else:
			print(other.name, "不借给", self.name, "钱")

	def show_info(self):
		print(self.age, "岁的", self.name, "存有", self.money, "元钱")


# 以下为类的使用
xiaomaomao = Human('xiaomaomao', 1)
xiaoxiaomao = Human('xiaoxiaomao', 1)

xiaoxiaomao.teach(xiaomaomao, 'Python')	# xiaoxiaomao 教 xiaomaomao 学 Python
xiaomaomao.teach(xiaoxiaomao, 'Java')	# xiaomaomao 教 xiaoxiaomao 学 Java

xiaoxiaomao.works(1000)		# xiaoxiaomao 工作赚了 1000 元钱

xiaomaomao.borrow(xiaoxiaomao, 200)		# xiaoxiaomao 借给 xiaomaomao 200 元钱

xiaoxiaomao.show_info()		# 1 岁的 xiaoxiaomao 存有 800 元钱
用于类的函数

isinstance(obj, class_or_tuple) # 返回这个对象obj是否某个类class或某些类的实例,如果是则返回True,如果否则返回False
type(obj) # 返回对象的类型

class Dog:
	pass

class Cat:
	pass

animal = Dog()
isinstance(animal, Dog)
isinstance(animal, Cat)

isinstance(animal, (Cat, int, list)) # False
isinstance(animal, (Cat, int, Dog))	# True

type(animal) 	# <class '__main__.Dog'>, 等同于animal.__class__
类变量 class variable(也叫类属性)

类变量是类的属性,此属性属于类
作用:用来记录类的相关数据
说明:类变量可以通过类直接访问;类变量可以通过类的实例直接访问;类变量可以通过此类的实例的__class__属性间接访问
示例:

# 此示例示意类变量的定义和使用

class Human:
	count = 0 			# 创建一个类变量

# 通过类直接访问
print("Human的类变量count=", Human.count)		# Human的类变量count= 0
Human.count = 100
print(Human.count)		# 100

# 通过类的实例直接访问类变量
human1 = Human()
print(human1.count)		# 100

# 通过类示例.__class__访问类变量
human2 = Human()
human2.count = 200
print(human2.count)		# 200
print(human2.__class__.count)		# 100

类变量的应用案例:用类变量来记录对象的个数

class Car:
	count = 0		# 创建类变量,用来记录汽车对象的总数
	def __init__(self, info):
		print(info, "被创建")
		self.data = info 		# 记录传入数据
		self.__class__.count = self.__class__.count + 1	# 让车的总数加1

	def __del__(self):
		print(self.data, "被销毁")
		self.__class__.count = self.__class__.count - 1	# 当车被销毁时自动减1

print(Car.count)	# 0
b1 = Car("BYD")
print(Car.count)	# 1
b2 = Car("BMW")
print(Car.count)	# 2
b3 = Car("Audi")
print(Car.count)	# 3
类的文档字符串

类内第一个没有赋值给任何变量的字符串是类的文档字符串
说明:类的文档字符串用类的__doc__属性可以访问;类的文档字符串可以用help()函数查看
示例:

'''
模块的标题
此模块示意类的文档字符串
'''
class Car:
	'''
	此类用来描述车的对象的行为
	这是Car类的文档字符串
	'''
	def run(self, speed):
		'''
		车的run方法
		'''
		pass
类的__slots__列表

作用:限定一个类的实例只能有固定的属性(实例变量),通常为防止错写属性名而发生运行时错误
示例:

# 此示例示意类变量__slots__列表的作用

class Student:
	__slots__ = ['name', 'score']
	def __init__(self, name, score):
		self.name = name
		self.score = score

s1 = Student('xiaomaomao', 100)
print(s1.score)		# 100
s1.socre = 90     	# 不加slots时写错了属性名,但在运行时不会报错;添加了slots列表后运行会报错
print(s1.score)		# 100

说明:含有__slots__列表的类创建的实例对象没有__dict__属性,即此实例不用字典保存对象的属性(实例变量)
在这里插入图片描述

类方法 @classmethod

类方法是描述类的行为的方法,类方法属于类
说明:(1)类方法需要用@classmethod装饰器定义;(2)类方法至少有一个形参,第一个形参用于绑定类,约定写为’cls’; (3)类和该类的实例都可以调用类方法;(4)类方法不能访问此类创建的实例的属性(只能访问类变量)
示例:

# 此示例示意类方法的定义和用法

class Car:
	count = 0  # 类变量

	@classmethod
	def getTotalCount(cls):
		'''此方法为类方法,第一个参数为cls,代表调用此类方法'''
		return cls.count

	@classmethod
	def updateCount(cls, number):
		cls.count = cls.count + 1


print(Car.getTotalCount())   # 用类来调用类方法 0
#Car.count = Car.count + 1   # 不提倡直接直接操作类变量

Car.updateCount(1)	# 使用类方法操作类变量
print(Car.getTotalCount())   # 1

c1 = Car() # 创建一个对象
c1.updateCount(100)	# Car类的实例也可以调用类方法
print(c1.getTotalCount()) 	# 101

# 此示例示意类方法的定义和用法

class Car:
	count = 0  # 类变量

	@classmethod
	def getInfo(cls):
		return cls.count

c1 = Car()	# 创建一个对象
c1.count = 100
print(c1.getInfo())		# 0 拿到的是类里面的变量
静态方法 @staticmethod

问题:(1)类方法属于类
(2) 实例方法属于该类的实例
(3) 类内能不能有函数,这个函数不属于类,也不属于实例。这样的方法是静态方法。
静态方法不属于类,也不属于类的实例,它相当于定义在类内的普通函数,只是它的作用域属于类
示例:

# 此示例示意静态方法的创建和使用

class A:
	@staticmethod
	def myadd(x, y):
		'''
		此方法为静态方法
		此方法的形参不需要传入类或实例
		'''
		return x + y

print('1+2=', A.myadd(1, 2))
a = A()
print('100+200=', a.myadd(100, 200))
继承(inheritance)和派生(derived)

继承:继承是指从已有的类中派生出新类,新类具有原类的行为,并能扩展新的行为。
派生:派生是从一个已有类中衍生(创建)新类, 在新类上可以添加新的属性和行为
继承和派生的目的:继承是延续旧类的功能;派生是为了在旧类的基础上添加新的功能
作用:
(1)用继承派生机制,可以将一些共有功能加在基类中,实现代码的共享
(2) 在不改变基类的基础上改变原有功能
继承/派生的名词:
基类(base class),超类(super class),父类(father class),派生类(derived class),子类(child class)

单继承

语法:
class 类名(基类名):
语句块
说明:单继承是指派生类由一个基类衍生出来的类
示例:

class Human:
	'''此类用来描述人类的共性行为'''
	def say(self, that):
		print("say: ", that)
	def walk(self, distance):
		print("walk: ", distance, "kms")


class Student(Human):
	def study(self, subject):           
		print("studying: ", subject)


class Teacher(Student):
	def teach(self, subject):
		print("teaching: ", subject)


h1 = Human()
h1.say("todday is very cold")
h1.walk(5)

s1 = Student()
s1.say("todday is very cold")

t1 = Teacher()
t1.say("tommorrow is Saturday")
t1.walk(6)
t1.teach("object oriented")
t1.study("piano")

继承说明:任何类都直接或间接继承自object类,object类是一切类的超类(祖类)
类的__base__属性:__base__属性用来记录此类的基类
在这里插入图片描述

覆盖(override)

覆盖:覆盖是指在有继承关系中的类中,子类中实现了与基类同名的方法,在子类实例调用该方法时,实例调用的是子类中的覆盖版本的方法,这种现象叫做覆盖。
示例:

# 此示例示意覆盖的用法

class A:
	def work(self):
		print("A.work()被调用")

class B(A):
	'''B继承自A类'''
	def work(self):
		print("B.work()被调用")

a = A()
a.work()		# A.work()被调用

b = B()
b.work()		# B.work()被调用
b.__class__.__base__.work(b)		# A.work()被调用

子类对象显式调用基类方法的方式:
基类名.方法名(实例, 实例调用传参)
super函数:
super(type, obj)返回绑定超类的实例
super()返回绑定超类的实例,等同于super(class, 实例方法的第一个参数)(必须在方法内调用)
示例:

# 此示例示意super函数来调用父类的覆盖版本方法

class A:
	def work(self):
		print("A.work()被调用")

class B(A):
	'''B继承自A类'''
	def work(self):
		print("B.work()被调用")

	def super_work(self):
		# 在方法内调用父类的方法
		# self.work()	# B.work()
		# super(B, self).work()	# A.work()
		super().work()  # A.work()



b = B()
b.__class__.__base__.work(b)		# 调用父类的work方法 A.work()被调用

super(B, b).work()		# 调用超类的方法 A.work()被调用

b.super_work()		# A.work()被调用

显示调用基类的初始化方法:
当子类中实现了__init__方法时,基类的__init__方法并不会被自动调用,此时需要显式调用。
示例:

# 此示例示意子类对象用super方法显示调用基类的__init__方法

class Human:
	def __init__(self, n, a):
		'''此方法为人的对象添加姓名和年龄属性'''
		self.name = n
		self.age = a

	def infos(self):
		print("name: ", self.name)
		print("age: ", self.age)


class Student(Human):
	def __init__(self, n, a, s=0):
		super().__init__(n, a)
		self.score = s

	def infos(self):
		super().infos()
		print("score: ", self.score)
		

s1 = Student("xiaoxiaomao", 1, 100)
s1.infos()
用于类的函数

issubclass(cls, class_or_tuple): 判断一个类是否继承自其它的类,如果此类cls是class或tuple中的一个派生子类则返回True,否则返回False
示例:

class A:
	pass

class B(A):
	pass

class C(B):
	pass

issubclass(C, (A, B))		# True
issubclass(C, (int, str)) 	# False
issubclass(C, A)	# True

查看python内建类的继承关系的方法:
help(builtins)

封装 enclosure

封装是指隐藏类的实现细节,让使用者不用关心这些细节,封装的目的是让使用者尽可能少的使用实例变量(属性)进行操作。
私有属性:python类中,以双下划线‘__’开头,不以双下划线结尾的标识符为私有成员,在类的外部无法直接访问。

# 此类示意使用私有属性和私有方法

class A:
	def __init__(self):
		self.__p1 = 100 	# __p1为私有属性,在类的外部不可以访问

	def test(self):
		print(self.__p1)  # 可以访问,A类的方法可以调用A类的私有方法

	def __m1(self):
		'''私有方法,只有在类的内部方法才能调用此方法'''
		print("我是A类的__m1方法")

a = A()		# 创建对象
#print(a.__p1) 	# 在类外看不到__p1属性,访问失败
a.test()		# 100
a.__m1()		# 出错,无法调用私有方法
多态(polymorphic)

字面意思:“多种状态”
多态是指在继承/派生关系的类中,调用基类对象的方法,实现能调用子类的覆盖版本方法的现象叫多态
说明:多态调用的方法与对象相关,不与类型相关;Python的全部对象都只有“运动时状态(动态)”,没有“C++/Java”里的“编译时状态(静态)”
示例:

# 此示例示意多态

class Shape:
	def draw(self):
		print("Shape.draw被调用")

class Point(Shape):
	def draw(self):
		print("正在画一个点")

class Circle(Point):
	def draw(self):
		print("正在画一个圆")

def my_draw(s):
	s.draw()  	 # 调用那个类具体要看传进来的参数是哪个类中的

s1 = Circle()
s2 = Point()
my_draw(s1)	# 调用Circle里的draw
my_draw(s2) # 调用Point里的draw
多继承 multiple inheritance

多继承是指一个子类继承自两个或两个以上的基类
语法:
class 类名(基类名1, 基类名2, …):
语句块
说明:(1) 一个子类同时继承自多个父类,父类中的方法可以同时被继承下来;
(2) 如果两个父类中有同名的方法,而在子类中又没有覆盖此方法时,调用结果难以确定
示例:

# 此示例示意多继承语句和使用

class Car:
	def run(self, speed):
		print("以", speed, "公里/小时的速度行驶")

class Plane:
	def fly(self, height):
		print("飞机以海拔", height, "的高度飞行")

class PlaneCar(Car, Plane):
	'''
	PlaneCar同时继承自汽车类和飞机类
	'''

p1 = PlaneCar()
p1.fly(10000)
p1.run(300)

多继承的问题(缺陷)
标识符(名字空间冲突的问题),要谨慎使用多继承
示例:

# 此示例示意多继承可能出现的问题

# 小猫猫写了一个类A
class A:
	def m(self):
		print("A.m()被调用")

# 小小猫写了一个类B
class B:
	def m(self):
		print("B.m()被调用")

# 诗诗用小猫猫和小小猫写的类
class AB(A, B):
	pass

ab = AB()
ab.m()		# A.m()被调用,但是B.m()中也有m方法,在实际复杂的问题中很难控制哪一个被调用
多继承的MRO(method resolution order)问题

类内的__mro__属性用来记录继承方法的查找顺序
示例:

# 此示例示意在多继承中的方法查找顺序问题

class A:
	def m(self):
		print("A.m")

class B:
	def m(self):
		print("B.m")

class C(A):
	def m(self):
		print("C.m")
		super().m() # super()是按照MRO顺序来打印的,而不是按照父类的继承来调用的

class D(B, C): 
	def m(self):
		print("D.m")
		super().m()

d = D()
print(D.__mro__) # (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
d.m()  # 调用方法的顺序D,B,C,A		
函数重写 override

重写是指在自定义的类内添加相应的方法,让自定义的类生成的对象(实例)像内建对象一样进行内建的函数操作

对象转字符串函数重写:

repr(obj)返回一个能代表此对象的表达式字符串,通常eval(repr(obj)) == obj
def repr(self):
return 能够表达self内容的字符串
str(obj)通过给定的对象返回一个字符串(这个字符串通常是给人看的)
示例:
def str(self):
return 人能看懂的字符串

# 没有重写str和repr方法前调用str方法
class MyNumber:
	def __init__(self, value):
		self.data = value
	
n1 = MyNumber(100)
print(str(n1)) # 调用object的str方法
print(repr(n1)) # 调用object的repr方法

# 打印出如下结果
# <__main__.MyNumber object at 0x10d9f0668>
# <__main__.MyNumber object at 0x10d9f0668>
# 重写str和repr方法
class MyNumber:
	def __init__(self, value):
		self.data = value

	def __str__(self):
		return "数字:%d" % self.data

	def __repr__(self):
		return 'MyNumber(%d)' % self.data
	
n1 = MyNumber(100)
print(str(n1)) # 数字:100
print(repr(n1)) # MyNumber(100)

n2 = eval("MyNumber(100)")
print(n2) # 数字:100

说明:
(1) str(obj)函数优先调用obj.str()方法返回字符串
(2) 如果obj没有__str__()方法,则调用obj.repr()方法返回的字符串
(3) 如果obj没有__repr__()方法,则调用object类的__repr__()实例方法显示格式的字符串

数值转换函数的重写

complex(self): complex(obj) 函数调用
int(self): int(obj) 函数调用
float(self): float(obj) 函数调用
bool(self): bool(obj) 函数调用
示例:

# 此示例示意自定义的类MyNumber能够转为数字值类型

class MyNumber:
	def __init__(self, v):
		self.data = v

	def __repr__(self):
		return "MyNumber(%d)" % self.data

	def __int__(self):
		'''此方法用于int(obj)函数重载,必须返回整数
			此方法通常用于制订自定义对象如何转为整数的规则'''
		return 10000

n1 = MyNumber(100)
print(type(n1)) # <class '__main__.MyNumber'>

n = int(n1)
print(type(n)) # <class 'int'>
内建函数的重写

abs abs(obj)
len len(obj)
reversed reversed(obj)
round round(obj)
示例:

# 自定义一个MyList类,与系统内建的类一样,用来保存有先后顺序关系的数据

class MyList:
	'''自定义列表类'''
	def __init__(self, iterator=[]):
		self.data = [x for x in iterator]

	def __repr__(self):
		return "MyList(%r)" % self.data

	def __abs__(self):
		#return MyList([abs(x) for x in self.data])
		# 也可以用生成器表达式来生成
		return MyList((abs(x) for x in self.data))

	def __len__(self):
		return len(self.data)

myl = MyList([1, -2, 3, -4])
print(myl)
print(abs(myl))

myl2 = MyList(range(10))
print(myl2)
print('myl2 的长度是:', len(myl2))
print('myl 的长度是:', len(myl))
布尔测试函数的重写

格式:def bool(self):

作用:用于bool(obj)函数取值;
用于if语句真值表达式中
用于while语句真值表达式中
说明:(1) 优先调用__bool__()方法取值
(2) 如果不存在__bool__()方法,则用__len__()方法取值后判断是否为零值,如果不为零返回True,否则返回False
(3) 如果再没有__len__()方法,则直接返回True
示例:

# 自定义一个MyList类,与系统内建的类一样,用来保存有先后顺序关系的数据

class MyList:
	'''自定义列表类'''
	def __init__(self, iterator=[]):
		self.data = [x for x in iterator]

	def __repr__(self):
		return "MyList(%r)" % self.data

	def __abs__(self):
		#return MyList([abs(x) for x in self.data])
		# 也可以用生成器表达式来生成
		return MyList((abs(x) for x in self.data))

	# def __len__(self):
	# 	return len(self.data)

	def __bool__(self):
		return False

myl = MyList([1, -2, 3, -4])
print(bool(myl)) # 没有bool方法就用len方法,不为0返回真;没有len时永远返回真;如果有bool方法,优先调用bool方法

if myl:
	print("myl 是真值")
else:
	print("myl 是假值")
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章