Python魔法之旅-魔法方法(14)

目錄

一、概述

1、定義

2、作用

二、應用場景

1、構造和析構

2、操作符重載

3、字符串和表示

4、容器管理

5、可調用對象

6、上下文管理

7、屬性訪問和描述符

8、迭代器和生成器

9、數值類型

10、復制和序列化

11、自定義元類行為

12、自定義類行為

13、類型檢查和轉換

14、自定義異常

三、學習方法

1、理解基礎

2、查閱文檔

3、編寫示例

4、實踐應用

5、閱讀他人代碼

6、參加社區討論

7、持續學習

8、練習與總結

9、注意兼容性

10、避免過度使用

四、魔法方法

44、__length_hint__方法

44-1、語法

44-2、參數

44-3、功能

44-4、返回值

44-5、說明

44-6、用法

45、__lshift__方法

45-1、語法

45-2、參數

45-3、功能

45-4、返回值

45-5、說明

45-6、用法

46、__lt__方法

46-1、語法

46-2、參數

46-3、功能

46-4、返回值

46-5、說明

46-6、用法

五、推薦閱讀

1、Python筑基之旅

2、Python函數之旅

3、Python算法之旅

4、博客個人主頁

一、概述

1、定義

????????魔法方法(Magic Methods/Special Methods,也稱特殊方法或雙下劃線方法)是Python中一類具有特殊命名規則的方法,它們的名稱通常以雙下劃線(`__`)開頭和結尾

????????魔法方法用于在特定情況下自動被Python解釋器調用,而不需要顯式地調用它們,它們提供了一種機制,讓你可以定義自定義類時具有與內置類型相似的行為。

2、作用

????????魔法方法允許開發者重載Python中的一些內置操作或函數的行為,從而為自定義的類添加特殊的功能

二、應用場景

1、構造和析構

1-1、__init__(self, [args...]):在創建對象時初始化屬性。
1-2、__new__(cls, [args...]):在創建對象時控制實例的創建過程(通常與元類一起使用)。
1-3、__del__(self):在對象被銷毀前執行清理操作,如關閉文件或釋放資源。

2、操作符重載

2-1、__add__(self, other)、__sub__(self, other)、__mul__(self, other)等:自定義對象之間的算術運算。
2-2、__eq__(self, other)、__ne__(self, other)、__lt__(self, other)等:定義對象之間的比較操作。

3、字符串和表示

3-1、__str__(self):定義對象的字符串表示,常用于print()函數。
3-2、__repr__(self):定義對象的官方字符串表示,用于repr()函數和交互式解釋器。

4、容器管理

4-1、__getitem__(self, key)、__setitem__(self, key, value)、__delitem__(self, key):用于實現類似列表或字典的索引訪問、設置和刪除操作。
4-2、__len__(self):返回對象的長度或元素個數。

5、可調用對象

5-1、__call__(self, [args...]):允許對象像函數一樣被調用。

6、上下文管理

6-1、__enter__(self)、__exit__(self, exc_type, exc_val, exc_tb):用于實現上下文管理器,如with語句中的對象。

7、屬性訪問和描述符

7-1、__getattr__, __setattr__, __delattr__:這些方法允許對象在訪問或修改不存在的屬性時執行自定義操作。
7-2、描述符(Descriptors)是實現了__get__, __set__, 和__delete__方法的對象,它們可以控制對另一個對象屬性的訪問。

8、迭代器和生成器

8-1、__iter__和__next__:這些方法允許對象支持迭代操作,如使用for循環遍歷對象。
8-2、__aiter__, __anext__:這些是異步迭代器的魔法方法,用于支持異步迭代。

9、數值類型

9-1、__int__(self)、__float__(self)、__complex__(self):定義對象到數值類型的轉換。
9-2、__index__(self):定義對象用于切片時的整數轉換。

10、復制和序列化

10-1、__copy__和__deepcopy__:允許對象支持淺復制和深復制操作。
10-2、__getstate__和__setstate__:用于自定義對象的序列化和反序列化過程。

11、自定義元類行為

11-1、__metaclass__(Python 2)或元類本身(Python 3):允許自定義類的創建過程,如動態創建類、修改類的定義等。

12、自定義類行為

12-1、__init__和__new__:用于初始化對象或控制對象的創建過程。
12-2、__init_subclass__:在子類被創建時調用,允許在子類中執行一些額外的操作。

13、類型檢查和轉換

13-1、__instancecheck__和__subclasscheck__:用于自定義isinstance()和issubclass()函數的行為。

14、自定義異常

14-1、你可以通過繼承內置的Exception類來創建自定義的異常類,并定義其特定的行為。

三、學習方法

????????要學好Python的魔法方法,你可以遵循以下方法及步驟:

1、理解基礎

????????首先確保你對Python的基本語法、數據類型、類和對象等概念有深入的理解,這些是理解魔法方法的基礎。

2、查閱文檔

????????仔細閱讀Python官方文檔中關于魔法方法的部分,文檔會詳細解釋每個魔法方法的作用、參數和返回值。你可以通過訪問Python的官方網站或使用help()函數在Python解釋器中查看文檔。

3、編寫示例

????????為每個魔法方法編寫簡單的示例代碼,以便更好地理解其用法和效果,通過實際編寫和運行代碼,你可以更直觀地感受到魔法方法如何改變對象的行為。

4、實踐應用

????????在實際項目中嘗試使用魔法方法。如,你可以創建一個自定義的集合類,使用__getitem__、__setitem__和__delitem__方法來實現索引操作。只有通過實踐應用,你才能更深入地理解魔法方法的用途和重要性。

5、閱讀他人代碼

????????閱讀開源項目或他人編寫的代碼,特別是那些使用了魔法方法的代碼,這可以幫助你學習如何在實際項目中使用魔法方法。通過分析他人代碼中的魔法方法使用方式,你可以學習到一些新的技巧和最佳實踐。

6、參加社區討論

????????參與Python社區的討論,與其他開發者交流關于魔法方法的使用經驗和技巧,在社區中提問或回答關于魔法方法的問題,這可以幫助你更深入地理解魔法方法并發現新的應用場景。

7、持續學習

????????Python語言和其生態系統不斷發展,新的魔法方法和功能可能會不斷被引入,保持對Python社區的關注,及時學習新的魔法方法和最佳實踐。

8、練習與總結

????????多做練習,通過編寫各種使用魔法方法的代碼來鞏固你的理解,定期總結你學到的知識和經驗,形成自己的知識體系。

9、注意兼容性

????????在使用魔法方法時,要注意不同Python版本之間的兼容性差異,確保你的代碼在不同版本的Python中都能正常工作。

10、避免過度使用

????????雖然魔法方法非常強大,但過度使用可能會導致代碼難以理解和維護,在編寫代碼時,要權衡使用魔法方法的利弊,避免濫用。

????????總之,學好Python的魔法方法需要不斷地學習、實踐和總結,只有通過不斷地練習和積累經驗,你才能更好地掌握這些強大的工具,并在實際項目中靈活運用它們。

四、魔法方法

44、__length_hint__方法

44-1、語法
__length_hint__(self, /)Private method returning an estimate of len(list(it))
44-2、參數

44-2-1、self(必須)一個對實例對象本身的引用,在類的所有方法中都會自動傳遞。

44-2-2、/(可選)這是從Python 3.8開始引入的參數注解語法,它表示這個方法不接受任何位置參數(positional-only parameters)之后的關鍵字參數(keyword arguments)。

44-3、功能

? ? ? ? 為那些需要知道迭代器大致長度的函數或方法提供一個長度提示。

44-4、返回值

????????返回一個整數或None。

44-5、說明

? ?__length_hint__方法應該返回一個整數或None

44-5-1、如果返回整數,它應該是一個對迭代器長度的合理估計,這個估計可能并不總是準確的,但它應該盡可能接近實際長度。

44-5-2、如果迭代器長度未知或無法合理估計,則應返回None

44-6、用法
# 044、__length_hint__方法:
# 1、簡單的列表包裝器
class MyListWrapper:def __init__(self, lst):self.lst = lstdef __length_hint__(self):return len(self.lst)# 2、迭代器長度提示
class MyIterator:def __init__(self, numbers):self.numbers = numbersself.index = 0def __iter__(self):return selfdef __next__(self):if self.index < len(self.numbers):result = self.numbers[self.index]self.index += 1return resultraise StopIterationdef __length_hint__(self):return len(self.numbers) - self.index# 3、動態生成的序列
class DynamicSequence:def __init__(self, start, end):self.start = startself.end = enddef __iter__(self):return selfdef __next__(self):if self.start > self.end:raise StopIterationcurrent = self.startself.start += 1return currentdef __length_hint__(self):return self.end - self.start + 1 if self.start <= self.end else 0# 4、緩存長度的迭代器
class CachedLengthIterator:def __init__(self, iterable):self.iterable = iterableself._length = Nonedef __iter__(self):return iter(self.iterable)def __length_hint__(self):if self._length is None:self._length = sum(1 for _ in self.iterable)return self._length# 5、生成器長度提示(通常不準確,因為生成器是動態的)
def my_generator(n):for i in range(n):yield i
class GeneratorWrapper:def __init__(self, generator_func, *args, **kwargs):self.generator = generator_func(*args, **kwargs)self._hint = Nonedef __iter__(self):return iter(self.generator)def __length_hint__(self):if self._hint is None:# 注意:這只是一個示例,對于真正的生成器可能不準確self._hint = sum(1 for _ in self.generator)return self._hint# 使用示例:GeneratorWrapper(my_generator, 10)# 6、模擬數據庫查詢結果
class DatabaseQueryResult:def __init__(self, count):self.count = countdef __length_hint__(self):return self.count# 7、文件行數預估(基于文件大小)
class FileLineCounterApprox:def __init__(self, file_path, avg_line_length=100):  # 假設平均行長為100字節self.file_path = file_pathself.avg_line_length = avg_line_lengthdef __length_hint__(self):with open(self.file_path, 'rb') as file:return file.seek(0, 2) // self.avg_line_length  # 粗略估計# 8、樹形結構節點數預估
class TreeNode:def __init__(self, value, children=None):self.value = valueself.children = children if children is not None else []def __length_hint__(self):# 假設這是一個完全二叉樹,用于示例return (2 ** self.depth()) - 1 if self.is_full_binary_tree() else "unknown"def depth(self):# 需要實現一個計算樹深度的函數passdef is_full_binary_tree(self):# 需要實現一個檢查樹是否是完全二叉樹的函數pass# 注意:在實際應用中,樹的長度(即節點數)可能需要遞歸遍歷才能準確計算# 9、網絡請求結果集大小預估
class APIResult:def __init__(self, response_headers):self.response_headers = response_headersdef __length_hint__(self):# 假設API響應頭中包含了一個關于結果集大小的字段content_length = self.response_headers.get('X-Result-Set-Size', None)return int(content_length) if content_length is not None and content_length.isdigit() else "unknown"# 注意:這個預估是基于假設的HTTP頭字段,實際API可能不會有這樣的字段# 10、流式數據處理長度提示
class StreamProcessor:def __init__(self, stream):self.stream = streamself._processed_count = 0def process(self, chunk_size=1024):# 處理流數據,這里只是模擬for _ in range(chunk_size):# 假設每次處理一個數據單元self._processed_count += 1def __length_hint__(self):# 流數據長度通常未知,但可以提供已處理的數量return self._processed_count# 注意:流數據的長度通常是未知的,除非有額外的信息或上下文# 11、自定義集合大小預估
class CustomSet:def __init__(self, iterable=()):self._set = set(iterable)self._hint = Nonedef add(self, item):self._set.add(item)self._hint = None  # 清除長度提示緩存def remove(self, item):self._set.remove(item)self._hint = Nonedef __iter__(self):return iter(self._set)def __len__(self):return len(self._set)def __length_hint__(self):if self._hint is None:self._hint = len(self)  # 只有在需要時才計算長度return self._hint# 注意:在實際應用中,集合的大小可以直接通過len()函數獲取,但這里展示了如何使用__length_hint__進行緩存

45、__lshift__方法

45-1、語法
__lshift__(self, other, /)Return self << other
45-2、參數

45-2-1、self(必須)一個對實例對象本身的引用,在類的所有方法中都會自動傳遞。

45-2-2、 other(必須)表示與self進行左移操作的另一個對象或整數。

45-2-3、/(可選)這是從Python 3.8開始引入的參數注解語法,它表示這個方法不接受任何位置參數(positional-only parameters)之后的關鍵字參數(keyword arguments)。

45-3、功能

????????用于定義對象與左移位運算符<<的行為。

45-4、返回值

????????返回一個與self類型相同或兼容的對象,該對象表示self對象左移other位之后的結果。

45-5、說明

????????如果類沒有定義__lshift__方法,并且嘗試使用左移位運算符<<對其實例進行操作,將會引發一個TypeError。

45-6、用法
# 045、__lshift__方法:
# 1、二進制位移
class BinaryShift:def __init__(self, value):self.value = valuedef __lshift__(self, other):return BinaryShift(self.value << other)
if __name__ == '__main__':a = BinaryShift(4)b = a << 2  # 相當于 4 << 2 = 16print(b.value)  # 輸出 16# 2、整數列表左移
class IntList:def __init__(self, values):self.values = valuesdef __lshift__(self, other):if other < 0 or other >= len(self.values):raise ValueError("Invalid shift amount")return IntList(self.values[other:] + self.values[:other])
if __name__ == '__main__':lst = IntList([3, 5, 6, 8, 10, 11, 24])shifted = lst << 2  # 相當于 [6, 8, 10, 11, 24, 3, 5]print(shifted.values)  # 輸出 [6, 8, 10, 11, 24, 3, 5]# 3、字符串左移
class StringShift:def __init__(self, value):self.value = valuedef __lshift__(self, other):if other < 0:return StringShift(self.value[-other:] + self.value[:-other])elif other >= len(self.value):return StringShift(self.value)else:return StringShift(self.value[other:] + self.value[:other])
if __name__ == '__main__':s = StringShift("hello")shifted = s << 2  # 相當于 "llohe"print(shifted.value)  # 輸出 "llohe"# 4、時間戳左移(模擬時間偏移)
from datetime import datetime, timedelta
class TimestampShift:def __init__(self, timestamp):self.timestamp = timestampdef __lshift__(self, other):# 假設 other 是天數return TimestampShift(self.timestamp + timedelta(days=other))
if __name__ == '__main__':now = datetime.now()ts = TimestampShift(now)future = ts << 10  # 10天后的時間print(future.timestamp)  # 輸出10天后的日期時間# 5、圖形對象的水平移動
class Shape:def __init__(self, x, y):self.x = xself.y = ydef __lshift__(self, other):return Shape(self.x + other, self.y)
if __name__ == '__main__':rect = Shape(10, 24)moved = rect << 5  # 向右移動5個單位print(moved.x, moved.y)  # 輸出 15 24# 6、權重調整(模擬權重左移)
class WeightedItem:def __init__(self, value, weight):self.value = valueself.weight = weightdef __lshift__(self, other):# 假設 other 是權重增加的因子(例如,左移1位相當于權重乘以2)return WeightedItem(self.value, self.weight * (2 ** other))
if __name__ == '__main__':item = WeightedItem('apple', 1)item_with_higher_weight = item << 1  # 權重變為 2print(item_with_higher_weight.weight)  # 輸出 2# 7、顏色深度調整(模擬顏色通道值的左移)
class Color:def __init__(self, r, g, b):self.r = rself.g = gself.b = bdef __lshift__(self, other):# 假設 other 是亮度增加的因子(注意:這里需要確保值在有效范圍內)return Color(min(self.r << other, 255), min(self.g << other, 255), min(self.b << other, 255))
if __name__ == '__main__':red = Color(255, 0, 0)brighter_red = red << 1  # 增加亮度print(brighter_red.r, brighter_red.g, brighter_red.b)  # 輸出:255 0 0# 8、頻率調整(模擬音頻信號頻率的左移)
class AudioSignal:# 這里僅作為示例,實際音頻處理會更復雜def __init__(self, frequencies):self.frequencies = frequenciesdef __lshift__(self, other):# 假設 other 是頻率增加的因子(這在實際中是不準確的,僅作示例)return AudioSignal([freq * (2 ** other) for freq in self.frequencies])
if __name__ == '__main__':signal = AudioSignal([100, 200, 300])higher_freq_signal = signal << 1  # 模擬頻率加倍print(higher_freq_signal.frequencies)  # 輸出:[200, 400, 600]# 9、隊列元素左移(刪除頭部元素并在尾部添加新元素)
class Queue:def __init__(self):self.items = []def enqueue(self, item):self.items.append(item)def dequeue(self):if self.is_empty():raise IndexError("Queue is empty")return self.items.pop(0)def is_empty(self):return len(self.items) == 0# 模擬左移(刪除頭部并添加新元素)def __lshift__(self, new_item):self.dequeue()self.enqueue(new_item)
if __name__ == '__main__':q = Queue()q.enqueue(1)q.enqueue(2)q.enqueue(3)print(q.items)  # 輸出 [1, 2, 3]q << 4  # 刪除1并添加4print(q.items)  # 輸出 [2, 3, 4]# 10、價格調整(模擬折扣)
class Price:def __init__(self, value):self.value = valuedef __lshift__(self, discount_factor):# 假設 discount_factor 是折扣的百分比(例如,左移1位代表打五折)# 注意:這里的實現僅作為示例,真實的折扣計算會更復雜return Price(self.value * (1 - discount_factor / 100))
if __name__ == '__main__':original_price = Price(100)discounted_price = original_price << 50  # 假設代表打五折print(discounted_price.value)  # 輸出 50.0# 11、時間線事件的前移
class TimelineEvent:def __init__(self, name, timestamp):self.name = nameself.timestamp = timestampdef __lshift__(self, time_delta):# 將事件前移指定的時間量self.timestamp -= time_delta
if __name__ == '__main__':event = TimelineEvent('Meeting', datetime.now())print(event.timestamp)  # 輸出當前時間event << timedelta(hours=1)  # 將事件前移1小時print(event.timestamp)  # 輸出前移1小時后的時間# 12、圖形界面中的元素左移
class GUIElement:def __init__(self, x, y):self.x = xself.y = ydef __lshift__(self, shift_amount):# 將元素向左移動指定的像素量self.x = max(0, self.x - shift_amount)  # 確保元素不會移出容器的左側邊界def __repr__(self):# 為了更友好地打印GUIElement對象return f"GUIElement(x={self.x}, y={self.y})"
# 假設的GUI容器類(僅用于演示)
class GUIContainer:def __init__(self):self.elements = []def add_element(self, element):# 添加元素到容器中(這里只是簡單地將元素添加到列表中)self.elements.append(element)
# 主程序
if __name__ == '__main__':# 創建一個GUI容器container = GUIContainer()# 創建一個GUI元素(按鈕)并添加到容器中(雖然在這里我們并不真正添加到GUI中)button = GUIElement(100, 50)# 假設有一個add_element方法添加到容器中(這里我們手動調用)container.add_element(button)# 將按鈕向左移動20像素button << 20  # 調用__lshift__方法# 打印按鈕的新位置print(button)  # 輸出類似:GUIElement(x=80, y=50)

46、__lt__方法

46-1、語法
__lt__(self, other, /)Return self < other
46-2、參數

46-2-1、self(必須)一個對實例對象本身的引用,在類的所有方法中都會自動傳遞。

46-2-2、 other(必須)表示與self進行比較的另一個對象。

46-2-3、/(可選)這是從Python 3.8開始引入的參數注解語法,它表示這個方法不接受任何位置參數(positional-only parameters)之后的關鍵字參數(keyword arguments)。

46-3、功能

????????用于定義對象之間“小于”關系的行為。

46-4、返回值

????????返回一個布爾值(True或False),表示self是否小于other。

46-5、說明

????????如果沒有在類中定義__lt__方法,并且嘗試使用<運算符對其實例進行比較,將會引發一個TypeError,除非該類的實例是某個內置類型的子類(如int、float、str等),這些內置類型已經定義了它們自己的__lt__方法。

46-6、用法
# 046、__lt__方法:
# 1、自定義整數類
class MyInt:def __init__(self, value):self.value = valuedef __lt__(self, other):if isinstance(other, MyInt):return self.value < other.valueelif isinstance(other, int):return self.value < otherelse:raise TypeError("Unsupported operand types for <: 'MyInt' and '{}'".format(type(other).__name__))
if __name__ == '__main__':a = MyInt(5)b = MyInt(10)print(a < b)  # True# 2、自定義字符串長度比較
class StringLength:def __init__(self, s):self.s = sdef __lt__(self, other):if isinstance(other, StringLength):return len(self.s) < len(other.s)elif isinstance(other, int):return len(self.s) < otherelse:raise TypeError("Unsupported operand types for <: 'StringLength' and '{}'".format(type(other).__name__))
if __name__ == '__main__':s1 = StringLength("apple")s2 = StringLength("banana")print(s1 < s2)  # True# 3、自定義日期類
from datetime import date
class MyDate:def __init__(self, year, month, day):self.date = date(year, month, day)def __lt__(self, other):if isinstance(other, MyDate):return self.date < other.dateelse:raise TypeError("Unsupported operand types for <: 'MyDate' and '{}'".format(type(other).__name__))
if __name__ == '__main__':d1 = MyDate(2024, 3, 13)d2 = MyDate(2024, 6, 4)print(d1 < d2)  # True# 4、自定義二維點類
class Point:def __init__(self, x, y):self.x = xself.y = ydef __lt__(self, other):if isinstance(other, Point):return (self.x, self.y) < (other.x, other.y)else:raise TypeError("Unsupported operand types for <: 'Point' and '{}'".format(type(other).__name__))
if __name__ == '__main__':p1 = Point(3, 6)p2 = Point(5, 11)print(p1 < p2)  # True# 5、自定義矩形面積比較
class Rectangle:def __init__(self, width, height):self.width = widthself.height = height@propertydef area(self):return self.width * self.heightdef __lt__(self, other):if isinstance(other, Rectangle):return self.area < other.areaelse:raise TypeError("Unsupported operand types for <: 'Rectangle' and '{}'".format(type(other).__name__))
if __name__ == '__main__':rect1 = Rectangle(3, 6)rect2 = Rectangle(5, 11)print(rect1 < rect2)  # True# 6、自定義字典按值排序比較(僅比較第一個值)
class ValueSortedDict:def __init__(self, dict_items):self.dict_items = sorted(dict_items.items(), key=lambda x: x[1])def __lt__(self, other):if isinstance(other, ValueSortedDict):return self.dict_items[0][1] < other.dict_items[0][1]else:raise TypeError("Unsupported operand types for <: 'ValueSortedDict' and '{}'".format(type(other).__name__))
if __name__ == '__main__':dict1 = {'a': 10, 'b': 24}dict2 = {'c': 10, 'd': 8}vsd1 = ValueSortedDict(dict1)vsd2 = ValueSortedDict(dict2)print(vsd1 < vsd2)  # False# 7、自定義分數類,按分數值比較
from fractions import Fraction
class FractionWrapper:def __init__(self, numerator, denominator):self.fraction = Fraction(numerator, denominator)def __lt__(self, other):if isinstance(other, FractionWrapper):return self.fraction < other.fractionelif isinstance(other, Fraction):return self.fraction < otherelse:raise TypeError("Unsupported operand types for <: 'FractionWrapper' and '{}'".format(type(other).__name__))
if __name__ == '__main__':frac1 = FractionWrapper(10, 24)frac2 = FractionWrapper(3, 6)print(frac1 < frac2)  # True# 8、自定義復數類,按模長比較
import math
class ComplexNumber:def __init__(self, real, imag):self.real = realself.imag = imag@propertydef modulus(self):return math.sqrt(self.real ** 2 + self.imag ** 2)def __lt__(self, other):if isinstance(other, ComplexNumber):return self.modulus < other.moduluselse:raise TypeError("Unsupported operand types for <: 'ComplexNumber' and '{}'".format(type(other).__name__))
if __name__ == '__main__':c1 = ComplexNumber(3, 6)c2 = ComplexNumber(5, 11)print(c1 < c2)  # True# 9、自定義時間戳類,按時間先后比較
from datetime import datetime, timezone
class Timestamp:def __init__(self, timestamp):self.timestamp = datetime.fromtimestamp(timestamp, tz=timezone.utc)def __lt__(self, other):if isinstance(other, Timestamp):return self.timestamp < other.timestampelif isinstance(other, datetime):return self.timestamp < otherelse:raise TypeError("Unsupported operand types for <: 'Timestamp' and '{}'".format(type(other).__name__))
if __name__ == '__main__':ts1 = Timestamp(1609459200)  # 2021-01-01 00:00:00 UTCts2 = Timestamp(1609545600)  # 2021-01-02 00:00:00 UTCprint(ts1 < ts2)  # True# 10、自定義二維點類,按字典序比較
class Point2D:def __init__(self, x, y):self.x = xself.y = ydef __lt__(self, other):if not isinstance(other, Point2D):return NotImplementedif self.x < other.x:return Trueelif self.x == other.x and self.y < other.y:return Truereturn Falsedef __repr__(self):return f"Point2D({self.x}, {self.y})"
if __name__ == '__main__':p1 = Point2D(1, 2)p2 = Point2D(2, 1)p3 = Point2D(1, 3)print(p1 < p2)  # Trueprint(p1 < p3)  # Trueprint(p2 < p3)  # False# 11、自定義圖書類,按價格或出版時間比較
from datetime import datetime
class Book:def __init__(self, title, author, price, publish_date):self.title = titleself.author = authorself.price = priceself.publish_date = datetime.strptime(publish_date, '%Y-%m-%d')def __repr__(self):return f"Book(title={self.title}, author={self.author}, price={self.price}, publish_date={self.publish_date.strftime('%Y-%m-%d')})"def __lt_by_price__(self, other):if not isinstance(other, Book):return NotImplementedreturn self.price < other.pricedef __lt_by_publish_date__(self, other):if not isinstance(other, Book):return NotImplementedreturn self.publish_date < other.publish_date
if __name__ == '__main__':book1 = Book("Python Programming", "Alice", 39.99, "2022-01-01")book2 = Book("Java for Beginners", "Bob", 29.99, "2021-05-15")book3 = Book("Database Management", "Charlie", 49.99, "2022-06-30")# 按價格比較print(book1.__lt_by_price__(book2))  # True,因為book1的價格比book2高print(book2.__lt_by_price__(book3))  # True,因為book2的價格比book3低# 按出版時間比較print(book1.__lt_by_publish_date__(book2))  # False,因為book1的出版時間比book2晚print(book2.__lt_by_publish_date__(book3))  # True,因為book2的出版時間比book3早# 12、自定義學生類,按成績比較
class Student:def __init__(self, name, score):self.name = nameself.score = scoredef __repr__(self):return f"Student(name={self.name}, score={self.score})"def __lt__(self, other):if not isinstance(other, Student):return NotImplementedreturn self.score < other.score
if __name__ == '__main__':student1 = Student("Myelsa", 85)student2 = Student("Bruce", 90)student3 = Student("Jimmy", 85)# 按成績比較print(student1 < student2)  # True,因為student1的成績比student2低print(student1 < student3)  # False,因為student1和student3的成績相同print(student2 < student3)  # False,因為student2的成績比student3高

五、推薦閱讀

1、Python筑基之旅

2、Python函數之旅

3、Python算法之旅

4、博客個人主頁

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/22061.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/22061.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/22061.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

在Debian系統上賦予普通用戶ping 權限

在Debian系統上&#xff0c;普通用戶默認情況下沒有權限使用 ping 命令&#xff0c;因為它需要發送 ICMP 包&#xff0c;這通常需要 root 權限。為了允許普通用戶使用 ping&#xff0c;可以設置 ping 命令的 setuid 位。以下是具體的步驟&#xff1a; 查找 ping 命令的位置&am…

2024年度自貢市社會民生重大科技計劃項目申報要求、時間流程

一、申報要求 申報項目需符合以下申報要求和申報指南要求&#xff0c;申報資料需在“自貢市科技綜合業務服務平臺”中的“自貢市重點科技計劃項目管理系統”上傳。 &#xff08;一&#xff09;項目申報單位要求。 1.項目申報單位包括項目牽頭單位和項目合作單位。 2.多家單…

【Python】pyinstaller打包時添加詳細信息

在要被打包的py文件同級目錄新建version.txt&#xff0c;寫入以下內容 # UTF-8 # # For more details about fixed file info ffi see: # http://msdn.microsoft.com/en-us/library/aa381058.aspx # VSVersionInfo(ffiFixedFileInfo(filevers(1, 4, 0, 5),prodvers(1, 4, 0, 5…

SpringBoot使用RabbitMQ實現延遲隊列

SpringBoot使用RabbitMQ實現延遲隊列 需求和目標名詞解釋實現方式引入依賴添加配置文件配置類死信隊列消費者即時隊列消費者延遲消息發送結果注意 需求和目標 商城系統&#xff0c;用戶下單后若15分鐘內仍未完成支付&#xff0c;則自動取消訂單&#xff0c;若已支付&#xff0c…

重組蛋白的定量定性方法,你了解嗎?

重組蛋白的定量和定性分析是蛋白質工程和生物技術中至關重要的步驟&#xff0c;用于確保蛋白質的表達、純度和功能性符合預期。以下是小編整理的一些常用的方法以及實驗介紹&#xff0c;希望這些方法幫助研究人員詳細了解重組蛋白的特性。 主要的定性方法 1 WB&#xff08;Wes…

AIGC 011-SAM第一個圖像分割大模型-分割一切!

AIGC 011-SAM第一個圖像分割大模型-分割一切&#xff01; 文章目錄 0 論文工作1論文方法2 效果 0 論文工作 這篇論文介紹了 Segment Anything (SA) 項目&#xff0c;這是一個全新的圖像分割任務、模型和數據集。SA 項目是一個具有里程碑意義的工作&#xff0c;它為圖像分割領域…

基于springboot的多媒體素材庫源碼數據庫

基于springboot的多媒體素材庫源碼數據庫 近年來&#xff0c;信息化管理行業的不斷興起&#xff0c;使得人們的日常生活越來越離不開計算機和互聯網技術。首先&#xff0c;根據收集到的用戶需求分析&#xff0c;對設計系統有一個初步的認識與了解&#xff0c;確定多媒體素材庫…

迎七一黨史知識競賽答題怎么做

迎七一黨史知識競賽答題&#xff0c;不僅是對于黨史知識的檢驗&#xff0c;更是對于參賽者學習態度和綜合能力的考量。在參與這類競賽時&#xff0c;我們需要做好充分的準備&#xff0c;掌握一定的答題技巧&#xff0c;才能取得好的成績。 首先&#xff0c;我們要深入了解競賽…

FFmpeg播放器的相關概念【1】

播放器框架 相關術語 ?容器&#xff0f;文件&#xff08;Conainer/File&#xff09;&#xff1a;即特定格式的多媒體文件&#xff0c;比如mp4、flv、mkv等。 ? 媒體流&#xff08;Stream&#xff09;&#xff1a;表示時間軸上的一段連續數據&#xff0c;如一段聲音數據、一段…

UFS Explorer Professional Recovery: 如何從啟用了 mSATA 緩存的 Drobo 設備中恢復數據

天津鴻萌科貿發展有限公司是 UFS Explorer Professional Recovery 數據恢復軟件的授權代理商。 UFS Explorer Professional Recovery 數據恢復軟件提供綜合性的解決方案&#xff0c;用于解決復雜的數據恢復案例&#xff0c;包括那些采用特殊存儲技術的案例&#xff0c;或介質受…

上海亞商投顧:創業板指震蕩收漲 超70家ST股跌停

上海亞商投顧前言&#xff1a;無懼大盤漲跌&#xff0c;解密龍虎榜資金&#xff0c;跟蹤一線游資和機構資金動向&#xff0c;識別短期熱點和強勢個股。 一.市場情緒 滬指昨日震蕩震蕩&#xff0c;創業板指走勢稍強&#xff0c;盤中一度漲超1%&#xff0c;黃白二線分化嚴重。算…

vue ts 導入 @/assets/ 紅色顯示的問題解決

vue ts 導入 /assets/ 紅色顯示的問題解決 一、問題描述 在使用的時候這樣導入會出現如上的錯誤。 在使用的時候&#xff0c;導入的類型也沒有對應的代碼提示&#xff0c;說明導入有問題。 二、解決 在 tsconfig.json 中添加如下內容&#xff1a; {"compilerOptions&…

AI大模型探索之路-實戰篇15: Agent智能數據分析平臺之整合封裝Tools和Memory功能代碼

系列篇章&#x1f4a5; AI大模型探索之路-實戰篇4&#xff1a;深入DB-GPT數據應用開發框架調研 AI大模型探索之路-實戰篇5&#xff1a;探索Open Interpreter開放代碼解釋器調研 AI大模型探索之路-實戰篇6&#xff1a;掌握Function Calling的詳細流程 AI大模型探索之路-實戰篇7…

模式識別判斷題

貝葉斯估計的方法類似于貝葉斯決策&#xff0c;也需要定義損失函數。&#xff08;正確&#xff09; 解釋&#xff1a;貝葉斯估計是一種基于貝葉斯定理的參數估計方法&#xff0c;它在估計參數時考慮了參數的先驗分布。與貝葉斯決策類似&#xff0c;貝葉斯估計也需要定義損失函數…

46.ThreadPoolExcutor接口

線程池狀態 ThreadPoolExcutor使用int高3位來表示線程池狀態&#xff0c;低29位表示線程數量 狀態高三位接收新任務處理阻塞隊列任務說明RUNNING111YYSHUTDOWN000NY不會接收新任務&#xff0c;但會處理阻塞隊列剩余任務&#xff0c;比較溫和&#xff0c;已經提交的任務都會執…

15.1 測試-重要性與testing包

1. 測試的重要性 1.1 單元測試 單元測試是針對一小部分代碼進行獨立地測試。 單元測試的對象通常是單個函數或方法&#xff0c;而要測試的是它在接受給定的輸入后&#xff0c;能否產生符合預期的輸出。 單元測試的作用主要表現在以下兩個方面&#xff1a; 驗證程序的最小…

C++ STL-迭代器函數對象適配器

目錄 一.迭代器 二. 函數對象 三. 適配器 一.迭代器 是一種通用的指針類型&#xff0c;可以用來遍歷 STL 容器中的元素。 具有以下作用和意義&#xff1a; 提供一種通用的方式來訪問容器中的元素。允許對不同類型的容器進行統一的操作。增強了代碼的靈活性和可擴展性。 一…

The Best Toolkit 最好用的工具集

The Best Toolkit 工欲善其事&#xff0c;必先利其器&#xff0c;整理過往工作與生活中遇到的最好的工具軟件 PDF合并等 PDF24 Tools PDF查看器 SumatraPDF 可以使用黑色來查看&#xff0c;相對不傷眼睛&#xff0c;也有電子書相關的閱讀器 Kindle pdf裁邊工具 briss 軟件卸載…

【C++題解】1085 - 尋找雷劈數

問題&#xff1a;1085 - 尋找雷劈數 類型&#xff1a;for循環 題目描述&#xff1a; 把整數 3025 從中剪開分為 30 和 25 兩個數&#xff0c;此時再將這兩數之和平方&#xff0c;計算結果又等于原數。 (3025)(3025)55553025 &#xff0c;這樣的數叫“雷劈數”。 求所有符合這…

Photoshop版本選擇及系統要求

1、ps2018cc/2020cc版本 適合新手&#xff0c;增加了很多智能化操作&#xff0c;非常方便好上手。 2020&#xff1a; 2、ps2015版本 cc2015版本不論是功能還是硬件上&#xff0c;都是不二選擇&#xff0c;適合于配置較低的電腦&#xff0c;該有的基本功能它都有。 3、2021/2…