CS61A:STRING REPRESENTATION

Python 規定所有對象都應該產生兩種不同的字符串表示形式:一種是人類可解釋的文本,另一種是 Python 可解釋的表達式。字符串的構造函數 str 返回一個人類可讀的字符串。在可能的情況下,repr 函數會返回一個計算結果相等的 Python 表達式。repr 的文檔字符串解釋了這個屬性:


repr(object) -> stringReturn the canonical string representation of the object.
For most object types, eval(repr(object)) == object.</span></span>

對表達式的值調用 repr 的結果是 Python 在交互式會話中打印的結果。

>>> 12e12
12000000000000.0
>>> print(repr(12e12))
12000000000000.0

如果不存在計算結果為原始值的表示形式,Python 通常會生成一個用尖括號括起來的描述。

>>> repr(min)
'<built-in function min>'
str 構造函數通常與 repr 重合,但在某些情況下提供更易解釋的文本表示形式。例如,我們看到 str 和 repr 之間的日期存在差異。
>>> from datetime import date
>>> tues = date(2011, 9, 12)
>>> repr(tues)
'datetime.date(2011, 9, 12)'
>>> str(tues)
'2011-09-12'

repr 函數總是在其參數上調用一個名為 __repr__ 的方法。

>>> tues.__repr__()
'datetime.date(2011, 9, 12)'

str 構造函數的實現方式與此類似:它對其參數調用名為 __str__ 的方法。

>>> tues.__str__()
'2011-09-12'

True 和 false 值。我們之前看到 Python 中的數字有一個真值;更具體地說,0 是 false 值,所有其他數字都是 true 值。事實上,Python 中的所有對象都有一個 truth 值。默認情況下,用戶定義類的對象被視為 true,但可以使用特殊的 __bool__ 方法來覆蓋此行為。如果對象定義了 __bool__ 方法,則 Python 會調用該方法來確定其真值。


例如,假設我們希望余額為 0 的銀行賬戶為 false。我們可以向 Account 類添加一個 __bool__ 方法來創建此行為。

>>> Account.__bool__ = lambda self: self.balance != 0

我們可以調用 bool 構造函數來查看對象的真值,并且可以在布爾上下文中使用任何對象。
>>> bool(Account('Jack'))
False
>>> if not Account('Jack'):print('Jack has nothing')
Jack has nothing


序列作。我們已經看到,我們可以調用 len 函數來確定序列的長度。

>>> len('Go Bears!')
9


len 函數調用其參數的 __len__ 方法來確定其長度。所有內置序列類型都實現了此方法。

>>> 'Go Bears!'.__len__()
9

__getitem__ 方法由元素選擇運算符調用,但也可以直接調用。

>>> 'Go Bears!'[3]
'B'
>>> 'Go Bears!'.__getitem__(3)
'B'

Callable 對象。在 Python 中,函數是一等對象,因此它們可以作為數據傳遞,并且具有與任何其他對象一樣的屬性。Python 還允許我們通過包含 __call__ 方法來定義可以像函數一樣“調用”的對象。使用此方法,我們可以定義一個行為類似于高階函數的類。

>>> def make_adder(n):def adder(k):return n + kreturn adder
>>> add_three = make_adder(3)
>>> add_three(4)
7
>>> class Adder(object):def __init__(self, n):self.n = ndef __call__(self, k):return self.n + k
>>> add_three_obj = Adder(3)
>>> add_three_obj(4)
7

復數可以用兩種幾乎等效的方式表示:矩形形式(實部和虛部)和極坐標形式(大小和角度)。有時矩形形式更合適,有時極性形式更合適。事實上,完全可以想象一個系統,其中復數以兩種方式表示,并且用于作復數的函數與任何一種表示形式一起工作。我們在下面實現這樣的系統。順便說一句,我們正在開發一個對復數執行算術運算的系統,作為使用泛型運算的程序的一個簡單但不切實際的示例。復數類型實際上內置于 Python 中,但在此示例中,我們將實現自己的類型。

>>> class Number:def __add__(self, other):return self.add(other)def __mul__(self, other):return self.mul(other)
>>> class Complex(Number):def add(self, other):return ComplexRI(self.real + other.real, self.imag + other.imag)def mul(self, other):magnitude = self.magnitude * other.magnitudereturn ComplexMA(magnitude, self.angle + other.angle)
  • ComplexRI?constructs a complex number from real and imaginary parts.
    ComplexRI?從實部和虛部構造一個復數。
  • ComplexMA?constructs a complex number from a magnitude and angle.
    ComplexMA?從大小和角度構造一個復數。
>>> from math import atan2
>>> class ComplexRI(Complex):def __init__(self, real, imag):self.real = realself.imag = imag@propertydef magnitude(self):return (self.real ** 2 + self.imag ** 2) ** 0.5@propertydef angle(self):return atan2(self.imag, self.real)def __repr__(self):return 'ComplexRI({0:g}, {1:g})'.format(self.real, self.imag)

Python 具有一個簡單的功能,用于從零參數函數動態計算屬性。@property 修飾器允許在沒有 call 表達式語法(表達式后面的括號)的情況下調用函數。ComplexRI 類存儲 real 和 imag 屬性,并按需計算大小和角度。

同樣,ComplexMA 類存儲 magnitude 和 angle,但每當查找這些屬性時,都會計算 real 和 imag。

>>> from math import sin, cos, pi
>>> class ComplexMA(Complex):def __init__(self, magnitude, angle):self.magnitude = magnitudeself.angle = angle@propertydef real(self):return self.magnitude * cos(self.angle)@propertydef imag(self):return self.magnitude * sin(self.angle)def __repr__(self):return 'ComplexMA({0:g}, {1:g} * pi)'.format(self.magnitude, self.angle/pi)

對幅值或角度的更改會立即反映在 real 和 imag 屬性中。

>>> ma = ComplexMA(2, pi/2)
>>> ma.imag
2.0
>>> ma.angle = pi
>>> ma.real
-2.0

泛型函數是適用于不同類型參數的方法或函數。我們已經看到了很多例子。Complex.add 方法是通用的,因為它可以將 ComplexRI 或 ComplexMA 作為 other 的值。這種靈活性是通過確保 ComplexRI 和 ComplexMA 共享一個接口獲得的。使用接口和消息傳遞只是用于實現泛型函數的幾種方法之一。在本節中,我們將考慮另外兩個:類型調度和類型強制。

假設,除了復數類之外,我們還實現了一個 Rational 類來精確表示分數。add 和 mul 方法表示與本章前面的 add_rational 和 mul_rational 函數相同的計算。

>>> from fractions import gcd
>>> class Rational(Number):def __init__(self, numer, denom):g = gcd(numer, denom)self.numer = numer // gself.denom = denom // gdef __repr__(self):return 'Rational({0}, {1})'.format(self.numer, self.denom)def add(self, other):nx, dx = self.numer, self.denomny, dy = other.numer, other.denomreturn Rational(nx * dy + ny * dx, dx * dy)def mul(self, other):numer = self.numer * other.numerdenom = self.denom * other.denomreturn Rational(numer, denom)
>>> from math import pi
>>> ComplexRI(1, 2) + ComplexMA(2, pi/2)
ComplexRI(1, 4)
>>> ComplexRI(0, 1) * ComplexRI(0, 1)
ComplexMA(1, 1 * pi)
能夠直接用運算符進行操作的原因是在number class中,就已經進行了__add__ , __mul__的運算符重載

內置函數 isinstance 接受一個對象和一個類。如果對象具有一個類,則該類是給定類或繼承自給定類,則返回 true。

>>> c = ComplexRI(1, 1)
>>> isinstance(c, ComplexRI)
True
>>> isinstance(c, Complex)
True
>>> isinstance(c, ComplexMA)
False

類型調度的一個簡單示例是 is_real 函數,該函數對每種類型的復數使用不同的實現。

>>> def is_real(c):"""Return whether c is a real number with no imaginary part."""if isinstance(c, ComplexRI):return c.imag == 0elif isinstance(c, ComplexMA):return c.angle % pi == 0
>>> is_real(ComplexRI(1, 1))
False
>>> is_real(ComplexMA(2, pi))
True

類型調度并不總是使用 isinstance 執行。對于算術,我們將為 Rational 和 Complex 實例提供一個具有字符串值的 type_tag 屬性。當兩個值 x 和 y 具有相同的type_tag時,我們可以直接用 x.add(y) 將它們組合在一起。如果沒有,我們需要一個 cross-type作。

>>> Rational.type_tag = 'rat'
>>> Complex.type_tag = 'com'
>>> Rational(2, 5).type_tag == Rational(1, 2).type_tag
True
>>> ComplexRI(1, 1).type_tag == ComplexMA(2, pi/2).type_tag
True
>>> Rational(2, 5).type_tag == ComplexRI(1, 1).type_tag
False

為了組合復數和有理數,我們編寫了同時依賴于它們的兩種表示形式的函數。下面,我們依賴于一個事實,即 Rational 可以近似地轉換為一個實數的 float 值。結果可以與復數組合。

>>> def add_complex_and_rational(c, r):return ComplexRI(c.real + r.numer/r.denom, c.imag)

乘法涉及類似的轉換。在極坐標形式中,復平面中的實數總是具有正大小。角度 0 表示正數。角度 pi 表示負數。

>>> def mul_complex_and_rational(c, r):r_magnitude, r_angle = r.numer/r.denom, 0if r_magnitude < 0:r_magnitude, r_angle = -r_magnitude, pireturn ComplexMA(c.magnitude * r_magnitude, c.angle + r_angle)

加法和乘法都是可交換的,因此交換參數 order 可以使用這些跨類型運算的相同實現。

>>> def add_rational_and_complex(r, c):return add_complex_and_rational(c, r)
>>> def mul_rational_and_complex(r, c):return mul_complex_and_rational(c, r)

我們使用 type_tag 屬性來區分參數的類型。也可以直接使用內置的 isinstance 方法,但 tags 簡化了實現。使用類型標簽還說明了類型調度不一定鏈接到 Python 對象系統,而是一種在異構域上創建泛型函數的通用技術。


__add__ 方法考慮兩種情況。首先,如果兩個參數具有相同的 type 標簽,則它假定第一個參數的 add 方法可以將第二個參數作為參數。否則,它會檢查名為 adders 的跨類型實現字典是否包含可以添加這些類型標簽的參數的函數。如果存在這樣的函數,cross_apply 方法會查找并應用它。__mul__ 方法具有類似的結構。

>>> class Number:def __add__(self, other):if self.type_tag == other.type_tag:return self.add(other)elif (self.type_tag, other.type_tag) in self.adders:return self.cross_apply(other, self.adders)def __mul__(self, other):if self.type_tag == other.type_tag:return self.mul(other)elif (self.type_tag, other.type_tag) in self.multipliers:return self.cross_apply(other, self.multipliers)def cross_apply(self, other, cross_fns):cross_fn = cross_fns[(self.type_tag, other.type_tag)]return cross_fn(self, other)adders = {("com", "rat"): add_complex_and_rational,("rat", "com"): add_rational_and_complex}multipliers = {("com", "rat"): mul_complex_and_rational,("rat", "com"): mul_rational_and_complex}

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

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

相關文章

LangChain緩存嵌入技術完全指南:CacheBackedEmbedding原理與實踐(附代碼示例)

一、嵌入緩存技術背景與應用場景 1.1 為什么需要嵌入緩存&#xff1f; 算力消耗問題&#xff1a;現代嵌入模型&#xff08;如text-embedding-3-small&#xff09;單次推理需要約0.5-1秒/文本 資源浪費現狀&#xff1a;實際業務中約30%-60%的文本存在重復計算 成本壓力&#…

精益數據分析(3/126):用數據驅動企業發展的深度解析

精益數據分析&#xff08;3/126&#xff09;&#xff1a;用數據驅動企業發展的深度解析 大家好&#xff01;一直以來&#xff0c;我都堅信在當今競爭激烈的商業環境中&#xff0c;數據是企業獲得競爭優勢的關鍵。最近深入研究《精益數據分析》這本書&#xff0c;收獲頗豐&…

wpf ScaleTransform

在WPF中&#xff0c;ScaleTransform是用于實現元素縮放的核心類&#xff0c;屬于System.Windows.Media命名空間下的變換類型。以下是其主要特性與使用方式的總結&#xff1a; ?核心屬性? ?縮放比例? ScaleX&#xff1a;水平方向縮放比例&#xff08;默認1.0&#xff0c;即…

用純Qt實現GB28181協議/實時視頻/云臺控制/預置位/錄像回放和下載/事件訂閱/語音對講

一、前言 在技術的長河中探索&#xff0c;有些目標一旦確立&#xff0c;便如同璀璨星辰&#xff0c;指引著我們不斷前行。早在2014年&#xff0c;我心中就種下了用純Qt實現GB28181協議的種子&#xff0c;如今回首&#xff0c;一晃十年已逝&#xff0c;好在整體框架和邏輯終于打…

0x01、Redis 主從復制的實現原理是什么?

Redis 主從復制概述 Redis 的主從復制是一種機制&#xff0c;允許一個主節點&#xff08;主實例&#xff09;將數據復制到一個或多個從節點&#xff08;從實例&#xff09;。通過這一機制&#xff0c;從節點可以獲取主節點的數據并與之保持同步。 復制流程 開始同步&#xf…

整活 kotlin + springboot3 + sqlite 配置一個 SQLiteCache

要實現一個 SQLiteCache 也是很簡單的只需要創建一個 cacheManager Bean 即可 // 如果配置文件中 spring.cache.sqlite.enable false 則不啟用 Bean("cacheManager") ConditionalOnProperty(name ["spring.cache.sqlite.enable"], havingValue "t…

深入探索如何壓縮 WebAssembly

一、初始體積&#xff1a;默認 Release 構建 我們從最基礎的構建開始&#xff0c;不開啟調試符號&#xff0c;僅使用默認的 release 模式&#xff1a; $ wc -c pkg/wasm_game_of_life_bg.wasm 29410 pkg/wasm_game_of_life_bg.wasm這是我們優化的起點 —— 29,410 字節。 二…

多角度分析Vue3 nextTick() 函數

nextTick() 是 Vue 3 中的一個核心函數&#xff0c;它的作用是延遲執行某些操作&#xff0c;直到下一次 DOM 更新循環結束之后再執行。這個函數常用于在 Vue 更新 DOM 后立即獲取更新后的 DOM 狀態&#xff0c;或者在組件渲染完成后執行某些操作。 官方的解釋是&#xff0c;當…

前端面試-自動化部署

基礎概念 什么是CI/CD&#xff1f;在前端項目中如何應用&#xff1f;自動化部署相比手動部署有哪些優勢&#xff1f;常見的自動化部署工具有哪些&#xff1f;舉例說明它們的區別&#xff08;如Jenkins vs GitHub Actions&#xff09;。如何通過Git Hook實現自動化部署&#xf…

架構生命周期(高軟57)

系列文章目錄 架構生命周期 文章目錄 系列文章目錄前言一、軟件架構是什么&#xff1f;二、軟件架構的內容三、軟件設計階段四、構件總結 前言 本節講明架構設計的架構生命周期概念。 一、軟件架構是什么&#xff1f; 二、軟件架構的內容 三、軟件設計階段 四、構件 總結 就…

GPTNet如何革新創意與效率

引言 人工智能正在以前所未有的速度改變我們的工作與生活方式&#xff0c;從智能寫作到視覺創作&#xff0c;AI工具已成為不可或缺的伙伴。在眾多平臺中&#xff0c;GPTNet以其強大的功能整合和直觀體驗嶄露頭角。它不僅匯集了GPT系列、Claude、Grok、Gemini等頂級對話模型&am…

【計網】SSL/TLS核心原理

序言 在HTTP協議中&#xff0c;信息是明文傳輸的&#xff0c;因此為了通信安全就有了HTTPS(Hyper Text Transfer Protocol over Secure Socket Layer)協議。HTTPS也是一種超文本傳送協議&#xff0c;在HTTP的基礎上加入了SSL/TLS協議&#xff0c;SSL/TLS依靠證書來驗證服務端的…

Web Components 開發與集成

以下是關于 Web Components 開發與集成 的系統知識梳理,涵蓋核心概念、高級特性、集成與優化等內容: 一、Web Components 核心概念 技術作用核心 APICustom Elements定義可復用的自定義 HTML 元素customElements.define()、生命周期鉤子(connectedCallback 等)Shadow DOM封…

day26 學習筆記

文章目錄 前言一、圖像顏色轉換1.HSV顏色空間2.顏色轉換 二、灰度化1.最大值法2.平均值法3.加權均值法 三、二值化1.全局閾值法1.閾值法(THRESH_BINARY)2.反閾值法(THRESH_BINARY_INV)3.截斷閾值法(THRESH_TRUNC)4.低閾值零處理(THRESH_TOZERO)5.超閾值零處理(THRESH_TOZERO_IN…

威鋒VL822-Q7T10GHUB芯片適用于擴展塢顯示器

一、概述 VL822-Q7T是VIA Lab&#xff08;威盛電子旗下專注于USB相關技術研發的子公司&#xff09;精心打造的一款高性能USB 3.1 Gen2集線器控制器芯片。在當今數字化時代&#xff0c;USB接口作為設備連接與數據傳輸的核心通道&#xff0c;其性能與穩定性至關重要。VL822-Q7T憑…

華為OD機試真題——最小的調整次數/特異性雙端隊列(2025A卷:100分)Java/python/JavaScript/C++/C語言/GO六種最佳實現

2025 A卷 100分 題型 本文涵蓋詳細的問題分析、解題思路、代碼實現、代碼詳解、測試用例以及綜合分析&#xff1b; 并提供Java、python、JavaScript、C、C語言、GO六種語言的最佳實現方式&#xff01; 2025華為OD真題目錄全流程解析/備考攻略/經驗分享 華為OD機試真題《最小的調…

關于 Spring Boot 微服務解決方案的對比,并以 Spring Cloud Alibaba 為例,詳細說明其核心組件的使用方式、配置及代碼示例

以下是關于 Spring Boot 微服務解決方案的對比&#xff0c;并以 Spring Cloud Alibaba 為例&#xff0c;詳細說明其核心組件的使用方式、配置及代碼示例&#xff1a; 關于 Spring Cloud Alibaba 致力于提供微服務開發的一站式解決方案! https://sca.aliyun.com/?spm7145af80…

常見的爬蟲算法

1.base64加密 base64是什么 Base64編碼&#xff0c;是由64個字符組成編碼集&#xff1a;26個大寫字母AZ&#xff0c;26個小寫字母az&#xff0c;10個數字0~9&#xff0c;符號“”與符號“/”。Base64編碼的基本思路是將原始數據的三個字節拆分轉化為四個字節&#xff0c;然后…

B樹、紅黑樹、B+樹和平衡二叉樹(如AVL樹)的區別

B樹、紅黑樹、B樹和平衡二叉樹&#xff08;如AVL樹&#xff09;的區別及優缺點的總結&#xff1a; 1. 平衡二叉樹&#xff08;AVL樹&#xff09; 結構&#xff1a;二叉搜索樹&#xff0c;每個節點的左右子樹高度差不超過1。平衡方式&#xff1a;通過旋轉&#xff08;左旋/右旋…

Python Cookbook-6.5 繼承的替代方案——自動托管

任務 你需要從某個類或者類型繼承&#xff0c;但是需要對繼承做一些調整。比如&#xff0c;需要選擇性地隱藏某些基類的方法&#xff0c;而繼承并不能做到這一點。 解決方案 繼承是很方便的&#xff0c;但它并不是萬用良藥。比如&#xff0c;它無法讓你隱藏基類的方法或者屬…