Python 中的异常

在 Python 中,EAFP 的风格很受青睐,这种写法能让代码更加简洁,还可以避免一些重复判断和多线程竞争的问题。为此,了解并熟练使用异常是很重要的。 异常类 首先来看一下 Python 内置的异常类(有省略): BaseException +-- SystemExit +-- KeyboardInterrupt +-- GeneratorExit +-- Exception +-- StopIteration +-- StopAsyncIteration +-- ArithmeticError +-- AssertionError +-- AttributeError +-- BufferError +-- EOFError +-- ImportError +-- LookupError +-- MemoryError +-- NameError +-- OSError +-- ReferenceError +-- RuntimeError +-- SyntaxError +-- SystemError +-- TypeError +-- ValueError +-- Warning BaseException 是所有异常的老祖宗,但很少会用到,通常我们只需要 Exception,比如自定义一个错误类型: # 命名习惯一般以 Error 结尾 class CustomError(Exception): def __init__(self, message, status): # 这里最好把参数都放进去,之后会统一存在 e....

09-15 · 3 min

Python Import 源码阅读

浅析一下 Python 中的 Import 机制。代码版本:3.11.0 - 4dd8219。 Module & Package Import 的对象就是各种各样的模块,即 Module。如何定义呢?官方文档这样描述: A module is a file containing Python definitions and statements. 实际上,Module 可以是 Builtin,也可以是 C extension,但最常见的存在形式还是 *.py 文件。 一个 Module 同时也可能是 Package,此时它从文件升级为目录,就可以拥有 Submodule 了。Package 分为两种: Regular package:这类 Package 必须包含一个 __init__.py 文件,代表了这个 Module(Package) 本身。 Namespace package:如果不存在 __init__.py,Python 会将其创建为此类 Package。Namespace package 的特殊之处在于同名的 Package 可以出现在多个目录下,而 Import 完成之后又可以统一使用。 不管是哪一种 Package,都会有 __path__ 属性,指向目录的路径。属性值是个列表,这对于 Namespace package 尤为重要。除此之外,一个 Module 还有: __name__:模块名称。 __file__:文件位置。 __package__:主要是为了在 Relative import 时计算起点位置。 如果是 Package 则设置为 __name__。 如果非 Package 则设置为 Parent package 的名称(Top-level 的 Module 应为空字符串)。 如果以脚本执行,那么取值为 None。 How to Import 一般情况下 Import 都是通过 import 关键字完成的,可分为两大类:...

09-10 · 6 min

游大理

来云南前只想好了去腾冲,并没有决定之后的行程,这样随性的旅行让我觉得自由。 至于其他的城市,小时候跟着家里去过大理和丽江,所以并不打算重游故地。不过,在腾冲结识的一位大叔极力推荐洱海的美景,还热情地拿出照片证明,于是我改变主意,既然不想这么快回家,大理又离得不远,就把它作为下一站吧。 落脚 大理的车站不比昆明,这本没什么,不太方便的是出来找不到厕所。一番折腾后,才在马路对面的巷子里找到了公厕。 打个车来到了预订的住处,与其说酒店,更像是高层的公寓被改造成了统一装修的房间,不过环境尚可。 住宿的位置在下关镇。后来才发现,这是个错误的决定,因为离景区太远了,更明智的选择是古城里面或周边的民宿。 地理位置大致如下(图里的大理镇就是古城): 图片来自豆瓣 - 在大理旅居的日子 简单收拾下,便去城里转了转。不得不说,这趟短行令人失望,街道两边满是小吃店,人声喧闹,让我觉得格格不入。浮躁、商业化是时隔近二十年后大理古城给我的初印象。 洱海 第二天到了下午才出门,一个重要原因是防晒。 之前在腾冲顶着大太阳走,一天下来发现小臂和鼻子都晒伤了,这才意识到云南紫外线的厉害。 虽然擦防晒很管用,但需要配合卸妆油冲洗。在网上看到还有喷雾类的产品,不知道可不可以省去这种麻烦。 前一天在京东下了单,上午便收到了,除了防晒,还买了个 U 盘。之所以买它是因为升级操作系统时不小心搞坏了 Grub,必须要 Live boot 修复。这也让我意识到作为 Linux 用户,随身携带 Live media 的重要性。 下关的风很大(大理有苍山雪,洱海月,上关花,下关风的说法),到了洱海边便风平浪静了。进入生态廊道后,有很多自行车可以租骑,路程很长,所以骑行观赏是个不错的选择。 这次的海边之行,让我真正领略到洱海之美,也动了留在大理的心思。 爸爸和女儿的对话很有爱 小哥的背影完美融合 美丽的洱海 云海笼罩的苍山 一路向前,天色渐晚,我又来到了古城。肚子有些饿,正好看到一位慈祥的老奶奶在摆摊,便决定尝尝。视频里的烤乳扇是大理特色的奶酪制品,加热烤软后再裹上玫瑰酱,甜香又有嚼头。 老人家一边做东西一边亲切地给我介绍大理的小吃,让我深深地感受到了当地人的热情。 佛乐 第三天依然过得很慵懒,虽然知道有很多美景未去,但游玩并不是我的目标。就在这天,我得到了一些期望的慰藉。 之前在豆瓣上联系了家月租的客栈,在古城内,所以下午又来到了这里。客栈的位置很好,紧挨着人民路,小间在一楼,价格便宜,800 一个月,包水电网。我对居住条件没有太高要求,所以觉得还不错,但因为无法就此留下,所以只是答应对方考虑一下。开店的是一对夫妇,大哥告诉我他们定居大理已经四年有余,给我讲了很多当地的风土人情,还说许多人来这里都是为了疗伤,有些选择离开,有些留了下来。最后聊到了饭辙,他们很少做饭,因为附近吃饭很方便,旁边有家本素拾堂,专做素食。我一听便来了兴致,正好晚饭没有着落。 大哥带我来到餐店门口,打了两句招呼,便扭头回去了。我按着看店大姐说的,拿起饭盒打了饭菜,津津有味地吃了起来。 虽然都是素菜,味道却不错。我看其中一道满是青椒,顺嘴问了句会不会很辣。有些出乎意料地,除了大姐,还有个在一旁吃饭的姑娘也加入回答我的问题,对话很是自然。这感觉很舒服,我便开了话匣子,问到店里播放的诵乐,说听得自己想哭。这好像触动了大姐,她提到很少人会有如此感觉,也许是我有缘,还建议我不妨尝试自然地让眼泪流出来。我深知自己是无法在旁人面前落泪的,连忙摆手婉拒。大姐很是理解,没再多说什么,我便自顾自地开始吃剩下的菜。 而后在城内转了转,之前的感觉犹在,仿佛心里打开了一道缺口,有些积压许久的东西缓缓流淌出来,让我在悲伤之中又有些许畅快。 大概是缘分牵引,我又回到了那个小店,打算问问住宿,其实是心里想再听听那诵经声。大姐见我回来,也没有过多诧异,我们便随意攀谈起来。说话之间又聊到了那首曲子,她说是佛乐,网上找不到,我也无意强求什么,只想再多听一会儿。大姐见状也不再打扰,为我泡了壶茶,径自收拾厨房去了。 云滇红,味道清香 这乐曲为女声吟唱,似乎只有一句,听来却不觉得枯燥。说实话,它让我感到久违的疲累,这反倒是件好事,因为我正苦于不知如何放下一些沉重的念头。不用装模作样,不用秉持信念,不用时刻准备战斗。如果能不那么执着,就像电影里说的,把手松开,是不是就可以拥有一切了。 如此一夜过去。那些反覆的杂念,无法消散的呓语,挥之不去的思绪,好像都随着昨日的乐声离去了。或许只是暂时的沉淀,未来还会再度泛起,我不能确定,但心确实有一点放空,还变得有些轻松。 最后一天要赶飞机,夜里难眠,莫名又想起了金刚经里写的: 过去心不可得,现在心不可得,未来心不可得。 好像更理解之前为什么不能放下了,总是在想,过去为何糟糕,未来会不会好。不管是否拥有,一旦想要把握,便会开始失去。心不可得,也就是心一直在变化,不会停留,就像时间一样。 如同在心流中,如果能抛下执念,做任何事情都会变得轻松和满足,也感受不到时光的流逝了。 是为合一的状态?我不知道,也许只需要,一件事一件事地去做就好了。 因为暂时没有做好留在这里的准备,所以还是要离开的。不过我想,待到时机成熟,一定要再来大理居住些日子。到时候,想要认识些有意思的人,多看看苍山雪与洱海月,再次享受这份独一无二的自由。

08-30 · 1 min

游腾冲

来到腾冲,主要是想找个地方散心。 之前有人告诉我: 你可能有时候过于认为自己的精力是无限的。 其实你身体很累,但你意识总是想支出更多的体力。 于是我想,可能什么都不做就会好起来。后来才发现,原来让自己休息并没有那么容易。 启程 苏州没有机场,所以要先乘高铁到上海,再坐地铁到浦东机场。这实在让我有些想念北京。 腾冲,是云南的一个县级市,隶属保山市。原本附近有个驼峰机场,到了当地才听说由于疫情已经停用很久了,因此要先飞到昆明,再乘高铁到保山,最后坐大巴到腾冲市区。因为没考虑到后面的车程,所以不得不在昆明住了一晚。不过我本来就喜欢自由行,所以并不在意。第一顿吃了小锅米线,味道很棒: 加帽儿(肉片),加臭豆腐(白色的,经过发酵),必须微辣 第二天一大早出发前往和顺古镇。 之前在网上订好了客栈,老板娘知道我从昆明过来,耐心地给我讲解路线,还让我到了市区联系司机来接。后来才知道,司机大叔和老板娘是夫妻,也都是和顺本地人,非常地热情好客。 一番周折,终于到了。大叔介绍说,前两周是人最多的时候,现在赶上开学季,所以游客很少。落个清静,正合我意。 我本来的房间在一楼,有些小,因为客人少,所以大叔直接给换到二楼的大间,幸福。 房间的名字很美 二楼做成了玻璃栈道的样子,阳光落下来的时候很美,但是走在上面实在有些刺激,生怕掉下来。 初探 简单收拾下,也算松了口气。天色尚早,是时候出去逛逛了。 碰到一只熟睡的小猫咪: 狗狗也睡着了: 走出小巷,外面风光无限。这边的天黑得很晚,八点之后才开始有傍晚的感觉。 不知走了多久,有些饿了,来到一家烧烤店。小店其实是家住的院子改造的,氛围很好: 店名叫小俩口,门外的夫妻俩负责烧烤,里面还有个老大爷坐镇。大爷一边招呼我一边热情地介绍当地的历史,眼神中充满了作为腾冲人的自豪与骄傲。 腾冲作为丝绸之路上的名镇,不论在商贸还是战争中都是交通要道,加上接近边境,很多人闯荡南洋后致富归来后反哺故土,让这里成为了著名侨乡。历史悠久,文化积淀深厚,自然风光秀丽,真的是一片神奇的土地。 吃的很快上来了,虽然我有所克制,但还是点多了: 木瓜水,酸甜可口 蘸料是当地特色的腌菜膏,酸辣鲜咸,有些接近东南亚的口味 小牛肉串 包浆豆腐,非常入味 吃饱喝足,我趁着夜色又溜达了一会儿,便回去休息了。 跷跷板 一天晚上散步时,望着漫漫夜色,听到蛙鸣四起,一阵无助的沮丧莫名涌了上来。 我看空地上有些健身器材,便挑了个脚蹬的架子踩了上去,随意摆动。这时来了三个人,看着像是当地的村民,一个年轻姑娘左右手各挽着年长些的一男一女,有说有笑地也来到这里。姑娘站上了我旁边的架子,玩了起来,我心情正差,看了她一眼,没有说话。那一对男女用当地话对了几句,一边一个坐上了跷跷板,男的自然重些,所以压在下面。姑娘见状便加入其中,一起帮忙把男的翘起,三个人玩闹得兴起,如同孩子般开心。我在一旁看着,心里微微起了些变化,也许是被她们的情绪感染,瞬间觉得生命并不复杂,大人也可以尽情享受跷跷板的快乐。 之后攀谈了起来,才知道她在小镇上的客栈打工,那对男女是老板夫妇。姑娘简单地介绍了下小镇的地形,又欢迎我来这里游玩,几个人便一起离开了。 我回忆着刚才发生的一切,有种被微光照亮的感觉。我好像与她们完全不在一个世界,但又有什么不同呢?我自认为要追求比她们更好的人生答案,但标准真的存在吗? 水黾 相比苏州接近四十度的高温,腾冲的天气很宜人,早晚甚至有些凉意。 上午下起了小雨 之后逛了逛当地的图书馆和博物馆,开始了解到另一条丝绸之路的伟大: 之前的游河西走廊就是北方丝绸之路了 马帮行走在商路上 落脚的客栈在小镇的西边,所以我一路向东,这里尽是湖边的美景。 当地的孩子直接下水游泳,看起来凉爽极了 走得累了,我便望着湖水发呆。水中趴满了一种小虫(后来才知道叫做水黾),细长的肢体,浮在水面上四处游窜。一阵风逆着吹来,将它们送回原处,甚至倒退。看这些小生物拼命地向前冲,却只是做无用功,我感到有些虚无缥缈。难道它们没有意识到一切如此无力么?我开始找寻,有没有一只会放弃抵抗、随风而去呢? 也许是数量太多,看不过来,直到最后我也没有找到想要的证明。但可能这本身也是一种证明吧,至少对这些水黾来说,生命不息,游动不止。 艾思奇 如果对哲学有好奇或喜爱,艾思奇纪念馆是一定要看看的。 他对马克思主义哲学的研究,让我感受了那个年代的脚踏实地。想到自己也看了几本哲学书,却仍然说不清一些基本概念,不禁有些惭愧。 不知道他们两个交谈时有没有知音相遇的感觉 离开 好久没出来旅行,东西带得不多。在腾冲的几天,意识到有些准备不足: 要做好防晒,云南的阳光很厉害,真的会晒伤。 防蚊药物最好也带上些,至少有个止痒的药膏。 记得做核酸,这边出入都要求 48 小时阴性报告,所以最好两天做一次。 临走的时候,碰上了突发状况,幸亏有客栈大叔帮忙。 因为没想到会打不到车,所以去车站之前没有预留很多的时间,我只好给客栈打电话。大叔当机立断,决定骑摩托车带我,因为这样可以抄小路,比开车更快。 我几乎从来没坐过摩托,身体紧绷地不行,大叔一边笑我一边宽慰让我放松。一路上风驰电掣,最后时间还提前了不少。我不迭地向大叔道谢,他爽朗一笑,招手让我赶紧去乘车了。 其实小镇周边还有不少景点,比如火山、温泉,但总体上更适合比较喜欢安静的人。对我来说,腾冲像快乐童年的一隅,没有烦恼,可以尽情地发呆、玩耍。如果有机会,我还会再回这里看看的。

08-30 · 1 min

Amazon OA 2022

分享一下今年准备 Amazon OA 时整理的题目。 按照低中高的难度简单分了下类,最后的难题能理解思路是最好的,不建议死记硬背。 Easy 1. Maximum quality sent via a channel 给一个 packets 数组和 k 个 channel,要求每个 channel 里面必须至少有一个数组里面的元素,每个元素只能在一个 channel 里面。其中 packets 中的元素数量是大于等于 k 的。要求算出所有channel中位数之和的最大值。 def solution(packets: List[int], channels: int) -> int: """ 将 packets 排序,依次把最大的一个元素分配给各 channel, 剩下的元素放到最后一个 channel。 """ packets.sort() total = 0 length = len(packets) for i in range(length - channels + 1, length): total += packets[i] rest = length - channels + 1 if rest % 2 == 0: sum = packets[(rest - 1) // 2] + packets[rest // 2] total += sum // 2 if sum % 2 == 0 else sum // 2 + 1 else: total += packets[rest // 2] return total 这是当时做 OA 的第一题,很轻松搞定,结果第二题非常 Hard,下面会提到。...

08-11 · 14 min