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 是假值")
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章