python黑魔法手冊(python魔法方法詳解)

本文目錄一覽:

Python有哪些黑魔法?

當然,Python的黑魔法是所有的內省和動態綁定。

例如,Python可以重新綁定解釋器的異常,以便在程序異常結束時可以進行一些自定義處理。

一旦你重置了異常鉤子,一旦你的代碼拋出一個異常,整個解釋器的環境將被ipdb接管,然後被用作交互模式。通常,我將檢查堆棧並pickle必要的對象,因此稍後再犯錯誤更容易。

由於IPython是一個非gui程序,所以即使在SSH中也可以使用它,這是SSH缺少IDE的完美解決方案。

動態綁定的另一個用途是,當程序依賴於修改後的庫時,可以將修改後的部分剝離,並在運行時動態綁定到相應的庫。

在內省中,Python可以通過dir()和help()函數獲取列表並幫助對象的成員,當您找不到庫文檔時,這些函數非常有用。只要開發人員在函數下面寫注釋,您就可以在幫助中看到它。

除了上面提到的特性之外,python還有一些小技巧,還有一些其他的答案。儘管它們中的許多都是語法上的糖,但它們可以使程序更有python:使用槽使成員靜態,您可以節省大量的內存。裝飾器,常用的功能,例如函數計時,也可以用來生成新的函數簽名。函數簽名可以影響傳遞檢查和ide完成,這對於具有不確定的長參數的函數非常有用。許多庫使用這種方法來處理不同版本的API。生成器,它可以為僅僅遍曆數據保存大量的內存。參數也展開了。

典型的例子是zip(listx)和鏈(listx),它們分別對應於轉置和連接。如果name==「main」:檢查主程序是否被調用,主程序必須與多處理並行使用這個框。例如,枚舉將列錶轉換為list2index可以用於((x,I)for I,枚舉列表中的x(listx))namedtuple,生成類似於C語言的結構,並支持所有元組的語法。不初始化該詞的defaultdictionary可以使用lambda來實現嵌套結構默認的結構的嵌套結構(lambda:defaultdictionary(int)),或者甚至是遞歸字典樹=lambda:defaultdictionary(樹)

有多少人按@蕭井陌大神給出的Python+Flask路線找到工作了

今天拿到offer了,一直圍觀此問題,終於可以輪到我裝逼了233

找工作前後花了整好一個月,我是一個月前的今天飛北平。不過第一張簡歷是上周日投的,投的知乎,然後被拒了,氣得我當場卸載了知乎app。然後每天投一份,直到昨天接到面試通知,今天面了一下午通過。

先說一下背景吧。說真的樓上你們這些科班出身甚至本來就從事web前後端的號稱花了一個月成功找到相關工作的,真是太打擊我們這些轉大行的了。

本人211土木專業本科,去年畢業還去工地吃了一年的屎,今年十一月裸辭。Python是大四學的,不過主要是為NumPy去的。

沒有任何項目經歷,截止到今天為止唯一的項目還是自己的博客,還是兩周前動工的,還沒寫完,前端真的太噁心了,再讓我寫css自殺。

沒做過ACM,沒用過Linux,沒寫過Vim。

沒學過網絡原理、操作系統、數據結構、數據庫。

Matlab技能點倒是豐富;我本科真的毀在數學建模上了。人在做,天在看,數學建模留禍患!

基本就是這樣。

到北平後的四周里有兩周都花在LeetCode上。不得不說LeetCode大法好啊,今天面試的算法題全是原題,我心裏跟撕了一萬條藏獒一樣爽。

剩下的時間基本都是在Flask里來回折騰,不過真的啃不動啊,我真的不懂什麼是TCP協議,什麼的socket。今天面試的web基礎問題全部跪了,唯一一道答上來的是「說說四種請求方式」,而我只知道get, post, put,太JB感人了。

面試全靠算法和Python基礎拿分,稍微問了問MySQL,問的很簡單,LeetCode的DB題比這些高到不知道哪裡去了;Python問的最高語法居然是生成器,我聽說有人都被問到修飾符了嚇得我趕緊買了本Python Pocket Reference通宵背了一遍;問了一個Maximum Subarray這個題,我做的時候是用的分治法做的,他們居然不滿意,非要引導我想出線性時間算法,但是我根本理解不了面試官在說啥,硬着頭皮想出一個雙指針算法居然得到了好評;二面的時候問的如何列表去重,空間複雜度和時間複雜度一步步做要求時的不同算法,然後讓我實現了一遍MergeSort;問了問Vim的幾個常用命令,小case。

然後HR來談待遇,就過了。。。

說一下公司,A輪融資完成,130人規模,O2O,待遇沒超過10k,爬蟲崗,雖然我從來沒有寫過爬蟲。

列一下書單吧:

Python類

Python CookBook,我一直把這書翻譯為Python黑魔法,尤其到元編程那章,真他媽黑。

Learning Python,大四時候就是抱着這書入門的,不過坑爹的中譯本居然把裝飾器、修飾符、元類這麼重要的部分給貿然截除了,我已經報警很多次了。

編寫高質量代碼——改善Python程序的91個建議,我完全用來當做查漏補缺的作用了,比如看看自己對mro的理解有沒有偏差什麼的。

Python Pocket Reference,純粹是為了應付面試,我怕他問我內置函數或者常用的標準庫。

沒有了

Web類

Flask Web開發,就是蕭大推薦的啦,雖然一遍一遍地看也還是停留在默寫出代碼的水平,但是我會努力把Flask源碼也背下來的!(大誤)

Head First HTML and CSS,我真的好想說,這本書的信息量密度好低啊,書又那麼貴又厚,害得我花了一天時間才看完,而且看完後基本忘完了。

深入理解Bootstrap,純粹是為了寫我的博客買的,買了以後才發現,媽的,不是有中文官網嗎。

圖解TCP/IP,花了一天看完,看完後覺得自我感覺良好,結果還是看不懂Python Cookbook第11章,很難過。

沒有了

其他

Learning SQL,好書啊,真的推薦,雖然概念解釋得稀爛,比如我是直到今天早上才知道應該怎麼回答「談談事務吧」,還是上網搜的。

GitHub入門,千萬別買,因為你就算看完後還是不知道該如何push你的代碼到你的repository,直接上GitHub看tutorial好了。

挑戰程序設計競賽,非常低調的書名,但是真的太棒了!我的數據結構和算法全是從上面學到的!應付面試的話圖論之後的不用看了,但是我不得不說網絡流那章非常精彩!

Vim實用技巧,非常棒,讓你逼格提升一個數量級。

沒有了

我不去繼續寫我的博客又在知乎裝逼了,今天的contribution又廢了。。

祝願所有的轉行生都一切順利!

說完了,求贊。

求《Python黑魔法指南2.0》全文免費下載百度網盤資源,謝謝~

《Python黑魔法指南2.0》百度網盤pdf最新全集下載:

鏈接:

?pwd=8mkk 提取碼:8mkk

簡介:作者(明哥)是一個從事雲計算多年的 Python 重度用戶,他把自已多年的 Python 編碼經驗整理成小冊子。

全書合計將近 5 萬字,收錄了近 100 條的 Python Tips,沒有長篇大論,每一篇都是精品,可以讓你一天之內,就能收穫別人幾年的 Python 技能及魔法知識。  

Python有哪些黑魔法

說到python黑魔法,必然要提到python的第三方協程庫gevent的底層實現——greenlet。

greenlet直接在內存層面,通過保存和替換Python進程的運行棧來實現不同協程的切換。

這個切換對於python解釋器是透明的,如果python解釋器對環境有感知的話,則每當協程切換的時候,它的感覺可能類似一個人前一秒還在在路上走路,下一秒突然自己又出現在了地鐵上。

對於普通python用戶而言,直接操作python的運行時棧,這就是在刀尖上跳舞有木有,這要求對內存的操作100%精確,任何錯誤都可能導致python進程崩潰!

作者又是如何又是如何來保證正確性呢?除了要熟悉python、操作系統、編譯器等等的底層機制,明確設計方案,還需要對不同的系統以及硬件環境做對應的

適配工作。我們在使用python的時候,在不同的系統或者硬件下感覺都一樣,那是因為python本身為我們屏蔽了底層細節,在做這種python底層

hack的事情的時候,顯然就沒那麼輕鬆了。

舉個例子,由於CPU有很多種,例如i386、x86_64、arm等等,每種CPU的設計不盡相同,於是作者為每種CPU寫了對應的彙編操作指令來完成棧的保存和替換,這些操作都是與操作系統和硬件高度綁定的。

雖然greenlet的實現這麼bt,但就是有人做到了,加上gevent的封裝,用起來比python自帶協程好用太多。

我想任何對python比較熟悉的童鞋,在初次接觸gevent的時候,都會好奇它是如何做到的,在進一步了解其底層greenlet實現機理之後,無不驚嘆其鬼斧神工。

這種事情就是那種,別人不說,你可能永遠不會想到的事情。

轉載

40.少有人知的 Python「重試機制」

為了避免由於一些網絡或其他不可控因素,而引起的功能性問題。比如在發送請求時,會因為網絡不穩定,往往會有請求超時的問題。

這種情況下,我們通常會在代碼中加入重試的代碼。重試的代碼本身不難實現,但如何寫得優雅、易用,是我們要考慮的問題。

這裡要給大家介紹的是一個第三方庫 – Tenacity ,它實現了幾乎我們可以使用到的所有重試場景,比如:

在使用它之前 ,先要安裝它

無條件重試,重試之間無間隔

無條件重試,但是在重試之前要等待 2 秒

只重試7 次

重試 10 秒後不再重試

或者上面兩個條件滿足一個就結束重試

在出現特定錯誤/異常(比如請求超時)的情況下,再進行重試

在滿足自定義條件時,再進行重試。

如下示例,當 test_retry 函數返回值為 False 時,再進行重試

如果想對一個異常進行重試,但是最多重試3次。

下面這個代碼是無效的,因為它會一直重試,重試三次的限制不會生效,因為它的條件是有順序的,在前面的條件會先被走到,就永遠走不到後面的條件。

如果你把 stop_after_attempt 寫到前邊,就沒有問題了。

當出現異常後,tenacity 會進行重試,若重試後還是失敗,默認情況下,往上拋出的異常會變成 RetryError,而不是最根本的原因。

因此可以加一個參數( reraise=True ),使得當重試失敗後,往外拋出的異常還是原來的那個。

當最後一次重試失敗後,可以執行一個回調函數

輸出如下

摘自黑魔法手冊

Python 有什麼奇技淫巧

我複製 的,僅供參考,版權歸原作者:

1. 元類(metaclass)

PyPy的源碼里有個pair和extendabletype

“””

Two magic tricks for classes:

class X:

__metaclass__ = extendabletype

# in some other file…

class __extend__(X):

… # and here you can add new methods and class attributes to X

Mostly useful together with the second trick, which lets you build

methods whose ‘self’ is a pair of objects instead of just one:

class __extend__(pairtype(X, Y)):

attribute = 42

def method((x, y), other, arguments):

pair(x, y).attribute

pair(x, y).method(other, arguments)

This finds methods and class attributes based on the actual

class of both objects that go into the pair(), with the usual

rules of method/attribute overriding in (pairs of) subclasses.

For more information, see test_pairtype.

“””

class extendabletype(type):

“””A type with a syntax trick: ‘class __extend__(t)’ actually extends

the definition of ‘t’ instead of creating a new subclass.”””

def __new__(cls, name, bases, dict):

if name == ‘__extend__’:

for cls in bases:

for key, value in dict.items():

if key == ‘__module__’:

continue

# XXX do we need to provide something more for pickling?

setattr(cls, key, value)

return None

else:

return super(extendabletype, cls).__new__(cls, name, bases, dict)

def pair(a, b):

“””Return a pair object.”””

tp = pairtype(a.__class__, b.__class__)

return tp((a, b)) # tp is a subclass of tuple

pairtypecache = {}

def pairtype(cls1, cls2):

“””type(pair(a,b)) is pairtype(a.__class__, b.__class__).”””

try:

pair = pairtypecache[cls1, cls2]

except KeyError:

name = ‘pairtype(%s, %s)’ % (cls1.__name__, cls2.__name__)

bases1 = [pairtype(base1, cls2) for base1 in cls1.__bases__]

bases2 = [pairtype(cls1, base2) for base2 in cls2.__bases__]

bases = tuple(bases1 + bases2) or (tuple,) # ‘tuple’: ultimate base

pair = pairtypecache[cls1, cls2] = extendabletype(name, bases, {})

return pair

先說extendabletype。嘛 其實注釋已經說得聽明白了,就是一個C#裏面的partial class的Python實現。

然後是pair和pairtype。pairtype就是根據兩個類創建一個新的類,這個類繼承自使用這兩個類的基類構造的pairtype(有點繞……)或者tuple。

有啥用呢?可以拿來實現multimethod。

class __extend__(pairtype(int, int)):

def foo((x, y)):

print ‘int-int: %s-%s’ % (x, y)

class __extend__(pairtype(bool, bool)):

def bar((x, y)):

print ‘bool-bool: %s-%s’ % (x, y)

pair(False, True).foo() # prints ‘int-int: False, True’

pair(123, True).foo() # prints ‘int-int: 123, True’

pair(False, True).bar() # prints ‘bool-bool: False, True’

pair(123, True).bar() # Oops, no such method

好像這個例子里元類只是個打輔助的角色,好玩的都在那個pair里……

再換一個。

class GameObjectMeta(type):

def __new__(mcls, clsname, bases, _dict):

for k, v in _dict.items():

if isinstance(v, (list, set)):

_dict[k] = tuple(v) # mutable obj not allowed

cls = type.__new__(mcls, clsname, bases, _dict)

all_gameobjects.add(cls)

for b in bases:

game_objects_hierarchy.add((b, cls))

return cls

@staticmethod

def _dump_gameobject_hierarchy():

with open(‘/dev/shm/gomap.dot’, ‘w’) as f:

f.write(‘digraph {\nrankdir=LR;\n’)

f.write(‘\n’.join([

‘”%s” – “%s”;’ % (a.__name__, b.__name__)

for a, b in game_objects_hierarchy

]))

f.write(‘}’)

def __setattr__(cls, field, v):

type.__setattr__(cls, field, v)

if field in (‘ui_meta’, ):

return

log.warning(‘SetAttr: %s.%s = %s’ % (cls.__name__, field, repr(v)))

這個是從我寫的三國殺遊戲中提取的一段代碼(點我簽名上的鏈接)。大意就是把class上所有可變的容器都換成不可變的,然後記錄下繼承關係。

曾經被這個問題坑過,class上的值是全局共享的,邏輯代碼一不小心修改了class上的值,單機測試的時候是測不出來的,然後放到線上……就悲劇了……當時絞盡腦汁沒有想到是這個問題硬生生的回滾了……發現了問題之後就加上了這個東西,不允許修改class上的東西。

記錄下繼承關係是為了畫類圖。

還有就是常用的做數據注入

metadata = {}

def gen_metafunc(_for):

def metafunc(clsname, bases, _dict):

meta_for = getattr(_for, clsname)

meta_for.ui_meta = UIMetaDescriptor()

if meta_for in metadata:

raise Exception(‘%s ui_meta redefinition!’ % meta_for)

metadata[meta_for] = _dict

return metafunc

from gamepack.thb import characters

__metaclass__ = gen_metafunc(characters.sakuya)

class Sakuya:

# 於是這個就不是類了, 而是作為數據存到了metadata這個dict里

char_name = u’十六夜咲夜’

port_image = ‘thb-portrait-sakuya’

figure_image = ‘thb-figure-sakuya’

miss_sound_effect = ‘thb-cv-sakuya_miss’

description = (

u’|DB完全瀟洒的PAD長 十六夜咲夜 體力:4|r\n\n’

u’|G月時計|r:|B鎖定技|r,準備階段開始時,你執行一個額外的出牌階段。\n\n’

u’|G飛刀|r:你可以將一張裝備牌當【彈幕】使用或打出。按此法使用的【彈幕】無距離限制。\n\n’

u’|DB(畫師:小D@星の妄想鄉,CV:VV)|r’

)

Ruby黨不要噴,我知道你們可以做的更優雅……

2. Python沙盒逃逸

刷新三觀的Python代碼

3. PEP302 New Import Hook

最近在把剛才提到的純Python遊戲向Unity引擎上移植。

玩過Unity的就會知道,Unity的遊戲的資源都是打包在一起的,沒有單獨的文件,Python解釋器就不高興了……於是寫了import hook,用Unity提供的API來讀py文件。

# -*- coding: utf-8 -*-

# — stdlib —

import imp

import sys

# — third party —

# — own —

from clr import UnityEngine, WarpGateController

# — code —

class UnityResourceImporter(object):

known_builtin = (

‘sys’,

‘imp’,

‘cStringIO’,

‘gevent_core’,

‘gevent_ares’,

‘gevent_util’,

‘gevent_semaphore’,

‘msgpack_packer’,

‘msgpack_unpacker’,

‘UnityEngine’,

)

def __init__(self, bases, unity_loader):

self.bases = bases

self.last_fullname = ”

self.last_text = ”

self.last_ispkg = False

self.unity_load = unity_loader

def find_module(self, fullname, path=None):

if fullname in sys.modules:

return self

head = fullname.split(‘.’)[0]

if head in self.known_builtin:

return None

rst = self.do_load_module(fullname)

if rst:

self.last_text, self.last_ispkg = rst

self.last_fullname = fullname

return self

else:

return None

def load_module(self, fullname):

if fullname in sys.modules:

return sys.modules[fullname]

if fullname != self.last_fullname:

self.find_module(fullname)

try:

code = self.last_text

ispkg = self.last_ispkg

mod = sys.modules.setdefault(fullname, imp.new_module(fullname))

mod.__file__ = “UnityResource: %s” % fullname

mod.__loader__ = self

if ispkg:

mod.__path__ = []

mod.__package__ = fullname

else:

mod.__package__ = fullname.rpartition(‘.’)[0]

co = compile(code, mod.__file__, ‘exec’)

exec(co, mod.__dict__)

return mod

except Exception as e:

UnityEngine.Debug.LogError(‘Error importing %s %s’ % (fullname, e))

raise ImportError(e)

def do_load_module(self, fullname):

fn = fullname.replace(‘.’, ‘/’)

asset = self.try_load(fn + ‘.py’)

if asset is not None:

return asset, False

asset = self.try_load(fn + ‘/__init__.py’)

if asset is not None:

return asset, True

def try_load(self, filename):

for b in self.bases:

asset = self.unity_load(b + filename)

if asset is not None:

return asset

return None

sys.meta_path.append(UnityResourceImporter([

‘Python/THBattle/’,

‘Python/Site/’,

‘Python/Stdlib/’,

], WarpGateController.GetTextAsset))

需要的extension module都靜態編譯到解釋器里了,所以沒考慮。

4. 可以批量執行操作的list

class BatchList(list):

def __getattribute__(self, name):

try:

list_attr = list.__getattribute__(self, name)

return list_attr

except AttributeError:

pass

return list.__getattribute__(self, ‘__class__’)(

getattr(i, name) for i in self

)

def __call__(self, *a, **k):

return list.__getattribute__(self, ‘__class__’)(

f(*a, **k) for f in self

)

class Foo(object):

def __init__(self, v):

self.value = v

def foo(self):

print ‘Foo!’, self.value

foo = Foo(1)

foo.foo() # Foo! 1

foos = BatchList(Foo(i) for i in xrange(10))

foos.value # BatchList([0, 1, 2, 3, …, 9])

foos.foo() # 你能猜到的

這個其實不算很黑魔法了,只是感覺很好用也有些危險,所以放上來。

暫時就想到這麼多了,以後發現了再補。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/270678.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-16 13:38
下一篇 2024-12-16 13:38

相關推薦

  • ArcGIS更改標註位置為中心的方法

    本篇文章將從多個方面詳細闡述如何在ArcGIS中更改標註位置為中心。讓我們一步步來看。 一、禁止標註智能調整 在ArcMap中設置標註智能調整可以自動將標註位置調整到最佳顯示位置。…

    編程 2025-04-29
  • 解決.net 6.0運行閃退的方法

    如果你正在使用.net 6.0開發應用程序,可能會遇到程序閃退的情況。這篇文章將從多個方面為你解決這個問題。 一、代碼問題 代碼問題是導致.net 6.0程序閃退的主要原因之一。首…

    編程 2025-04-29
  • Python創建分配內存的方法

    在python中,我們常常需要創建並分配內存來存儲數據。不同的類型和數據結構可能需要不同的方法來分配內存。本文將從多個方面介紹Python創建分配內存的方法,包括列表、元組、字典、…

    編程 2025-04-29
  • Python中init方法的作用及使用方法

    Python中的init方法是一個類的構造函數,在創建對象時被調用。在本篇文章中,我們將從多個方面詳細討論init方法的作用,使用方法以及注意點。 一、定義init方法 在Pyth…

    編程 2025-04-29
  • Python中讀入csv文件數據的方法用法介紹

    csv是一種常見的數據格式,通常用於存儲小型數據集。Python作為一種廣泛流行的編程語言,內置了許多操作csv文件的庫。本文將從多個方面詳細介紹Python讀入csv文件的方法。…

    編程 2025-04-29
  • 使用Vue實現前端AES加密並輸出為十六進制的方法

    在前端開發中,數據傳輸的安全性問題十分重要,其中一種保護數據安全的方式是加密。本文將會介紹如何使用Vue框架實現前端AES加密並將加密結果輸出為十六進制。 一、AES加密介紹 AE…

    編程 2025-04-29
  • 用不同的方法求素數

    素數是指只能被1和自身整除的正整數,如2、3、5、7、11、13等。素數在密碼學、計算機科學、數學、物理等領域都有着廣泛的應用。本文將介紹幾種常見的求素數的方法,包括暴力枚舉法、埃…

    編程 2025-04-29
  • Python學習筆記:去除字符串最後一個字符的方法

    本文將從多個方面詳細闡述如何通過Python去除字符串最後一個字符,包括使用切片、pop()、刪除、替換等方法來實現。 一、字符串切片 在Python中,可以通過字符串切片的方式來…

    編程 2025-04-29
  • 用法介紹Python集合update方法

    Python集合(set)update()方法是Python的一種集合操作方法,用於將多個集合合併為一個集合。本篇文章將從以下幾個方面進行詳細闡述: 一、參數的含義和用法 Pyth…

    編程 2025-04-29
  • Vb運行程序的三種方法

    VB是一種非常實用的編程工具,它可以被用於開發各種不同的應用程序,從簡單的計算器到更複雜的商業軟件。在VB中,有許多不同的方法可以運行程序,包括編譯器、發佈程序以及命令行。在本文中…

    編程 2025-04-29

發表回復

登錄後才能評論