標籤:

編程大佬不會寫tokenizer是不是一件很值得驕傲的事情?

你們口中的tokenizer是不是我了解的那個tokenizer???竟然讓我懷疑你們在討論的和我知道的是不是一個東西……感覺就好像在說一個武術高手可不可以徒手劈磚一樣……武術高手說我沒徒手劈過磚,但是我可以胸口碎大石


parser 算不上屠龍技,或者說 parser 很像知乎上所言的偽化生,大部分時候都是填語法設計的坑。

正常情況下只要拿著別人寫的 parser 拿 AST 開干就行了;從文本到 ast 這裡是繁瑣無聊並且如果別人幹了那麼自己沒必要再干一遍的事情。


Parser、Tokenizer 又不難,實現方式也沒啥新意。屠啥龍啊,這東西也就唬唬應屆生之類的,基礎知識而已。能拿這東西出來裝逼以及被這東西激怒的人,只能說修行還不夠吧。多寫代碼少撕逼。


身為高級工程師,不會 tokenizer 本身也不是什麼大事,他認為需要的時候再去學一下就好了,無非因為以前沒有打好基礎多花不少時間嘛。

只是作者認為自己寫的書是面向中高級 Python 程序員的,但是就其代碼來說,作者理解的高級可能和星巴克的大杯是同一個意思。

https://github.com/dongweiming/flask_reveal 是作者在 https://www.zhihu.com/question/37751951/answer/125640796 這個答案的評論里貼出來讓知友來寫的,作者放出自己的得意之作勇氣可嘉,只可惜代碼風格太差。

寫程序的道

好的程序應該如同代碼大全里提到的:寫程序應該關心 what,而不應該關心 how。

對於大段操作,直接寫一個函數進行封裝,這樣可以保證代碼是由很多小函數組成,而不是幾個大段大段的函數拼成。

路由需要處理的操作其實就是

1. 獲取數據

2. 處理數據

3. 返回數據

處理數據的操作放在 model 中單獨寫成一個函數就很合適,因為 route 本身只需要數據,並不需要關心數據是怎麼處理的,這就是寫 what 而不是寫 how。

在 route 中接收到處理之後的數據直接作為參數傳給 render_template。

@app.route(/foo, methods=[POST])
@login_required
def foo(username, title):
form = request.form
data = handled_data(request.query)
return render_template(foo.html, **data)

https://github.com/dongweiming/flask_reveal/blob/master/social/actions.py 也是完美違背寫程序應該寫 what 而不是寫 how 的原則,do_complete 函數的 url 隨處可見。就這點來看,作者寫代碼還不如屎殼郎滾糞球,至少後者是將糞滾成一個球而不是將糞撒得到處都是。

再說寫程序的術

1. 寫程序最重要的是直觀,而不是為了追求過分的簡潔。

儘管 python 是動態語言,但是也不應該使用各種隱式判斷

if user
if len(user)
while 1

這些都是不可取的,應該在判斷條件中將類型完整寫出

if user is not None
if len(user) &> 0
while True

2. 同時程序應該想辦法消除重複,這裡的重複有兩層意思

a. 大量相同的代碼,只有少部分不同

比如底下這兩個文件就屬於這樣的情況,這種當然應該寫一個函數來配置 SLConfig,根據不同的數據生成不同的配置項。https://github.com/dongweiming/flask_reveal/blob/master/templates/edit.html 中的

var SLConfig = {
current_user: {
name: "",
username: "{{ username }}",
pro: true
}
,
deck: {
user: {
name: "",
username: "{{ username }}"
},
id: "{{ data.tid }}",
slug: "{{ data.title }}",
title: "{{ data.title }}",
description: "{{ data.description }}",
access_token: "YnCGdsnvStQepRVEefzypwb9X64r",
published: {{ data.published|bool }},
transition: "{{ data.transition }}",
theme_font: "{{ data.theme_font }}",
theme_color: "{{ data.theme_color }}",
rolling_links: {{ data.rolling_links|bool }},
should_loop: {{ data.should_loop|bool }},
center: {{ data.center|bool }},
rtl: {{ data.rtl|bool }}
}
}

和 https://github.com/dongweiming/flask_reveal/blob/master/templates/deck.html 中的

var SLConfig = {
current_user: {
name: "",
username: "{{ username }}",
pro: false
}
,
deck: {
user: {
name: "",
username: "{{ username }}"
},
id: "{{ data.tid }}",
slug: "{{ data.tid }}",
title: "{{ data.title }}",
description: "{{ data.description }}",
access_token: "YnCGdsnvStQepRVEefzypwb9X64r",
published: {{ data.published|bool }},
transition: "{{ data.transition }}",
theme_font: "{{ data.theme_font }}",
theme_color: "{{ data.theme_color }}",
rolling_links: {{ data.rolling_links|bool }},
should_loop: {{ data.should_loop|bool }},
center: {{ data.center|bool }},
rtl: {{ data.rtl|bool }}
}
}

b. 看上去沒有相同的代碼,但是形式上是一致的

下面這段來自作者以前自豪的爬蟲代碼

https://github.com/dongweiming/Mtime/blob/master/spider.py

class Search(Spider):
搜索電影用的爬蟲
def make_query(self):
params = self.params
if not isinstance(params, OrderedDict):
d = OrderedDict()
d[Ajax_CallBack] = params[Ajax_CallBack]
d[Ajax_CallBackType] = params[Ajax_CallBackType]
d[Ajax_CallBackMethod] = params[Ajax_CallBackMethod]
d[Ajax_CrossDomain] = params[Ajax_CrossDomain]
d[Ajax_RequestUrl] = params[Ajax_RequestUrl]
d[t] = self.get_timestamp()
for i in range(20):
param = Ajax_CallBackArgument + str(i)
d[param] = params.get(param, 0)
return d
else:
return params

這裡 d 添加 key 的操作應該在函數中用循環完成。

作者的書里這樣的代碼( dongweiming/web_develop)隨處可見, 除了上面說的這些問題,還有一些連實習生都很難實現的操作,比如

  1. 使用 % 進行字元串格式化,
  2. 使用 Untitled 這樣敷衍的命名
  3. 在 html 中塞進 10000 多行 css 代碼而不是單獨引入一個 css 文件

本來不會 tokenizer 只是影響自己,但是以這樣的態度對待自己的讀者,實在是耽誤他們,不知道這些讀者有朝一日發現自己被如此初級水平的風格所教導,會有什麼感想。


我也不會寫。我也是非科班出生,沒有讀編譯原理這門課程,沒有做相關練習。

但是基本不影響我20多年的編程過程。

我想這就是計算機科學和計算機應用的區別。我一直做的只是在計算機應用領域的一些工作。工作我用python語言。完全不需要做json解析器這樣級別的工作。計算機科學已經為我準備了足夠的武器。在計算機科學的厚實基礎之上,計算機應用開發者並不需要學習太多知識。

計算機科學為計算機應用服務的。未來發展方向是編程越來越簡單,更多人都可以通過編程解決領域問題。比如人工智慧,有些人做底層演算法,有些人用這些演算法再醫學、教育領域去用起來。得益於底層計算機科學的積累,我們用人工智慧這樣nb的技術變得非常簡單,並不需要深入了解神經網路演算法細節。

人類文明的發展就是這樣的,在一個階梯之上,爆發大量新的應用。就如同蒸汽機的發明,引發整個工業革命。json的發明,革命了數據交換方法。一個新的低功耗晶元的發明,讓數碼產品變得更迷你。

但做計算機科學的,沒必要瞧不起計算機應用。計算機應用的也完全不必覺得自己不夠牛逼。大家只是在不同層面上創新而已。對做手機的來說,設計晶元就nb嗎?可能設計晶元對於微電子來說只是基本123級別的東西。做軟體也是這樣,搞個解析器就nb嗎?那只是編譯原理課程內容。真正有價值的還是創新,而不是簡單的學。

而且,在應用領域的創新,也可以是偉大的。就好比現在做大飛機,做航母的,也基本都是利用現有的基礎科學積累。但是仍然偉大。做一個好的軟體產品,裡面無數對業務模型的分析設計架構內容,同樣很多工程美感。這都是和計算機科學不同層面的創新。而真正在計算機科學層面出現創新,那肯定也不會是寫個分析器這門簡單。

其他工業分工細化很清楚了。但是計算機軟體層面並沒有那麼清晰。這導致計算機課程過於複雜,新手障礙。對整個軟體工業發展其實就是不利的。

但云計算的發展,python語言的流行,以及各種圖形化編程的發展,以及領域應用平台的崛起,讓軟體開發越來越簡單,這已經開啟了新的應用時代。我相信由此會帶來新的軟體應用革命,引發新的生態系統,和當年工業革命影響類似。

具體在python編程哲學裡面,對於我們這批做工程做應用的人,如果你還需要搞這些,首先會懷疑是否違背了簡單原則,違法了可維護性原則。是不是有人已經做好了類似的東西?工程上可能就是錯誤的選擇。

當然,我們還是需要知道很多基礎原理的。就好像我們需要知道發電原理,但是不需要去設計一個發電機。萬一有一天我們發現基礎領域不能滿足需求,需要去發明一個發電機,這時候就要去組織人去搞。但是一定是另外一批人,不會是搞應用的這批。

目前百分之80甚至更多的人,應該從事計算機應用領域。這才是合理的工業體系。基礎軟體工業還在快速發展,一定會提供更多更完善的基礎設施。在軟體應用領域,仍然存在大量的通用部分,但這部分內容系統也會再分層模塊化可被再利用。最終人工智慧來襲,輸入領域知識,自動出軟體,應用軟體開發也會消失了。這是一個非常長期的過程。說起來有些科幻就不胡謅了。


驕傲啦,當然驕傲啦

Python 有哪些優雅的代碼實現?讓自己的代碼更pythonic

大佬就是大佬,關閉評論區就贏了。

評論里 @靈劍 和 @林誠 都說的很對啊,不知道為何大佬呵呵一陣後就關了。幸虧靈劍贊數是這位大佬的五倍,否則也會像林誠一樣被這位大佬抓著沒回答沒贊在專欄里懟。要懟一起懟啊,乾脆連靈劍也一起圈出來在專欄里懟啊,跟這位大佬「論戰」的不止是一個人吧。

欺軟怕硬的貨罷了,low

這位大佬在專欄里,居然大言不慚的說「為啥1k人以下的不想和你撕呢?」,呵呵,厲害厲害,不撕還把人在自己專欄掛出來,這位大佬認為「撕逼,並在自己專欄把對方掛出來」這樣的行為就算是爺們了,佩服佩服,不愧是驕傲的大佬啊。我說你欺軟怕硬你別不承認,看來是驕傲的緊啊。

「我在網上一向自認為不裝逼,不匿名,不刪黑料,有問題就認」,大佬原話哦,首先第一點大佬就沒做到,其次最後一點大佬也沒做到,至於中間兩點呢,我們實在也是沒法判斷,所以大佬說的「一向自認為」我是認同的。

欺軟怕硬,還能這麼驕傲的,知乎這也是獨一份,服。

呵呵,去這位大佬的專欄下漫遊,居然在評論區看到了另外的大佬的支持一下,大佬的屁股坐的很正嘛,不分青紅皂白的就來支持了,這年頭怕是欺軟怕硬都需要抱團了。

中午不睡且還沒吃飯的更新:大家為啥在糾結 tokenizer 呢,問題的關鍵難道不是大佬的言行和做法嗎?

來自晚上的更新:大家似乎都在糾結tokenizer的問題,中午就說過了,這不是重點啊,大家先搞清楚前因後果吧,鏈接里都有。

還有一點,大家似乎都誤解了屠龍之技這個典,這典來自莊子。《莊子·列禦寇》:「朱泙漫學屠龍於支離益,殫千金之家,三年技成,而無所用其巧。」也是有點好笑,本就沒有龍,屠啥啊屠。


不是有ply嗎?自己寫確實是閑著蛋疼…這玩意真的是體力活,編譯原理的第一章或第二章內容而已…


每當看到類似標題,就會想是不是在挖當年 @薛非 vs @林建入 的梗

轉自:不好啦!來人啊!程序員約架了! - 知乎專欄


我認為學會寫一個簡單的tokenizer是有幫助的...

比如最簡單的問題:請問一個某種擴展語意下的正則表達式匹配的時間複雜度是多少?需要進行多少次計算?

這個時候你就需要有基礎的字元匹配自動機方面的知識了...

自動機我想一個稍有追求的程序員應該就知道有多大用,tokenizer大概應該是多數程序員設計的節點最多的自動機了...

還可以實現一個簡單的stringpiece庫,這個在某些應用場景下也有很大的作用,不展開...


tokenizer和parser都可以自動生成了,還當個寶呢?

說白了這種套路固定的東西,跟crud並沒有什麼不同。除非能突破現有的自動代碼生成框架。


隔壁搞Java的路過不禁說兩句。

1. 純手工tokenizer十幾年前當學生時寫過,但老實說工作後實在不怎麼用,簡單的字元串處理就上正則。複雜點有嵌套的就上antlr。原理我清楚,但說到「比賽寫tokenizer來比誰的水平高「,老實說我不敢打包票幹得過在校學生。

2. 就以這兩次tokenizer約戰來看,實在是非常無聊。要約戰不是應該雙方先同意然後第三方出題么。薛非那次約戰方也沒露什麼底細,C語言社區我也不熟,可能tokenizer在那裡真的天天要用,而且當時他說的是「咱們各自在github新開個項目寫tokenizer來比比」,不作惡意猜測的話,勉強還算公平,看完笑笑就算了。Python社區也搞這套就確實無聊了,甚至約戰方還自己爆出來,他自己近期正在搞編譯和正則引擎的開源(練手)項目。也就是他在這次約戰中毫無額外付出而且還偷跑了。如果這都占理,是不是每個人發表意見之前都得先寫個tokenizer項目鎮宅?事實上問題就轉化為,寫tokenizer的水平是不是判斷程序員水平的唯一標準?

3. 題目太具誤導性,典型的自立靶子,引來一眾大V強調編譯原理的重要性,我給好幾位我覺得言之有物的都點了贊。因為三觀正且切題,但是我個人真的非常不希望看見以後頻頻出現拿著一個「已經做好了的tokenizer項目」到處懟人的狀況。

4. 題目的鏈接和原始的撕逼答案我都看了,說點非常主觀的看法。作為java, clojure, ruby三修的搬磚人士,老實說我對某大佬列的技巧不是很有感。但懟他anti pattern,不利於重構和團隊合作,我覺得比較無厘頭。你一開始選動態語言,放棄類型系統,不就是為了寫起來快且爽么。你要易重構易合作,Java歡迎你呀。當然我不是說動態語言可以亂寫,但從重構和合作角度上去考慮,最多是個價值取向的問題。某大佬這點其實沒說錯,你覺得易重構易合作的代碼更優雅,自己去開個答案呀。在評論下懟,被回個「呵呵」表達不贊同,雖然不算很禮貌,但也不算太粗暴呀。按這位的說法,答主可以「不回答」,但不能「呵呵」。這很奇怪,不回答既可以理解為不理你,也可以理解為啞口無言。答主要明確表示不贊同但也不想理你,呵呵不是最直接的嗎。然後這位就突然爆了,又是誤人子弟,又是tokenizer。這就是我們想要的知乎氛圍?先不說事實上誰的技術好,即使你技術好就能理直氣壯在別人評論區里橫著走?更何況,用一個自己正在做的東西去約戰,別人不迎戰就說明自己懟贏了?

Python不是我的強項,僅有一點了解,我不是在這裡為某大佬的水平背書。只是說僅就此事來看,約戰方並不佔理,我個人很不希望實現tokenizer在知乎上成為評判一個程序員能力的新標準。


這玩意不是是個人就會寫嗎


這個問題不知道是誰添加的,不過看上去估計是個心眼很小的人。

事情的緣由我也看了,沒錯,一開始是那位大佬態度不好對人呵呵,但是後邊突然就冒出來編譯原理來說自己技術高的,說自己厲害的,你也總有一天會被人這樣擊敗,畢竟你總不可能自己從集成電路板開始造起來,總有你不懂的基礎知識。兩邊都沒就事論事,所以這是什麼狗屁問題


給人扣個大佬的帽子,然後按照大佬的標準批判一番。

人們都什麼自卑的嗎?還是踩人之前都要抬高一下對方凸現自己?


先不說董大佬技術水平如何(從一直以來的回答和文章來看,的確不能說很深入)。但是大佬樂於分享和整治python圈亂象的努力還是有目共睹的,是很多人的啟蒙者和指路明燈。不過成為大佬之後的確膨脹了,一言不合就「呵呵」,「我不跟小號說話」。

另一邊小林也是深得知乎技術撕逼真傳,想必也是深得林建入與薛非大戰三百回合最終祭出必殺技tokenizer大法而殺得薛非落荒而逃一役的真傳。一副氣急敗壞的醜陋嘴臉。且不說tokenizer這種ac自動機配合正則解析字元串的工作是否真的有「技術含量」。那個上來就是演算法導論我實現的差不多了(我反正是不信的)以顯示我在如何寫出pythonic代碼擁有絕對話語權的證明邏輯實在太無厘頭。

知乎有趣就在於誰都可以暢所欲言,說三道四,點贊或是反對,旗幟分明。但是呢,總有一部分人喜歡充當別人的人生導師。總是在一群人圍著篝火跳舞的時候蹦出來一盆水把火澆滅了,然後仰著頭淡定的提醒眾人別太高興了,懸崖就在旁邊。一副眾人皆醉我獨醒的嘴臉也很噁心,此時大家圍著篝火在慶祝什麼已經不重要了,我來展示我非凡的前瞻性和眼界才最重要。評論區就是這群人最活躍的地方。


嚇得虎軀一震,畢業幾年tokenizer和parser還真差不多都還給老師了。

趕緊在下半年學習計劃裡面加上,不然到時候被約架了不敢接多慫啊!(笑


鄙視提問者這種瞎帶節奏的,文章哪裡說不會寫tokenizer值得驕傲了?

人家明確說了,不是科班出生,大學期間沒搞這個,另外工作後還有很多東西要學,所以沒把這個玩意提到學習日程上,另外也不認為會寫個玩具tokenizer就能有什麼作為,如果工作需要肯定會去學的,這評論不是很正常嗎。


分頁阅读: 1 2 3