月初,陸續有網友收到微軟的Win10預約通知(也就是系統托盤區中那個Windows徽標),一些媒體也在渲染只有提前預約,才能將系統免費升級至Win10。但事實上這種說法并不嚴謹,準確地說只要你的系統和硬件符合Win10升級標準,那么即便不預約,也能在Win10發布后的一年內獲得免費升級。那么問題來了,既然預約與不預約結果都一樣,預約又有什么意義?今天小編就為大家解讀一下這預約背后的秘密!
軟件名稱: | Windows 10(內部預覽版10130) |
軟件版本: | 官方簡體中文版 |
軟件大小: | 3642.58MB |
軟件授權: | 免費 |
適用平臺: | Win10 |
下載地址: | http://dl.pconline.com.cn/download/359374.html |
圖01 只有預約才能升級Win10?
1. 分散微軟服務器壓力
對于像Windows這種體量巨大(近3GB)、用戶眾多的大家伙,任何一家公司的服務器都難以負擔如此龐大的集中式訪問。之前WP8升級時服務器宕機事件就給微軟敲響了一記警鐘,很明顯,微軟并不想讓類似的事情在Win10身上再次上演。這其中,預約升級便是一個很有效的解決方案。
預約其實是一種預下載機制,通俗來講就是你的電腦可以在7月29日Win10發布日前,將大部分升級所需文件提前下載至本地。這樣即便7月29日當天還有訪問要求,也會比之前少很多。一來可以分攤一下Windows Update服務器的整體壓力,二來也能讓用戶更快地完成升級,可以說這是一種最快的Win10升級方案了!
圖02 預約升級是一種最快的Win10升級方案
2. 沒有預約也能升級
如果你的電腦沒有預約Win10,也是可以正常升級的。具體方法是,7月29日正式發布后,之前安裝到用戶電腦中的“Get Windows 10”會自動發出通知,提示用戶下載并安裝整個Win10操作系統。當然由于沒有預約,這個過程就沒法提前了,只有等Win10正式發布后才會開始。而且推送的時間有早有晚,可能會在發布后第一時間推送,也有可能在數小時或數天后通知用戶,總之這一步會根據當時的服務器負載智能決定,但終究會比預約用戶晚一些!
圖03 沒有預約也能升級Win10
3. 沒有Get Windows 10怎么辦?
當然還有一部分用戶,由于種種原因并沒有安裝“Get Windows 10”這個程序,那么是否意味著他們將無緣Win10了呢?不然!其實微軟此次為Win10準備了多組升級途徑,通過Get Windows 10只是其一,如果用戶沒有安裝Get Windows 10也沒關系,后期還會通過Windows Update推送,當然這個的時效性恐怕就要更低了!
圖04 即便沒有安裝Get Windows 10,系統也會通過Windows Update推送
4. 直接下載或者安裝預覽版
如果實在對在線升級的速度沒信心,也可以直接下載ISO包。雖然微軟并未直接說明此次Win10發布是否會有ISO包,但作為一種最最傳統的升級方案,估計缺席的概率非常之低。當然你也可以現在就安裝一套Win10預覽版,一來可以提前感受一下新系統的風采,二來所有的Win10預覽版都可以無條件自動升級至正式版。而后者相比之下就比較簡單了,隨便到網上搜索一下,都能找到若干個獨立ISO文件,接下來開個第三方下載器直接開下就可以了。
圖05 安裝Win10預覽版也是一個不錯的辦法,任何Win10預覽版都可以無條件升級至正式版
寫在最后
總體來說,Win10的此次預約還是比較實在的,畢竟在沒有難度的情況下,大大降低了用戶的總體等待時間(但愿如此)。只是需要注意的是,正是由于這個“預下載”機制,你的電腦很可能會在7月29日前后無緣無故地下載大量文件,到時只要知道這是電腦在自動下載Win10安裝包就可以了。順便說一句,如果途中有什么變化,哪怕已經預約,也是可以隨時放棄的,微軟并不會強制用戶升級Win10!
址:https://digital.asahi.com/articles/ASP8T6KKWP8TUCLV00K.html
原題:予測できない手、次々 AIは名人優勢
摘自:朝日新聞
?作者:村上耕司、尾崎希海、大出公二、瀧澤文那
攝影:迫和義、尾崎希海
9:00
對局開始
?一力遼挑戰者率先進入對局室,過了沒多久,井山裕太名人進入了對局室。
上午9時,立會人張栩九段示意:“時間已到,請開始猜先”?。猜先過后,一力遼挑戰者執黑先行。
第一手棋落在了右上角小目,井山裕太名人隨即在左上角小目落子,第一天對局就此開始。
?10:00
研究室里,在場的是前年名人戰對局者
第1局?的立會人是張栩九段,擔任報紙解說的是芝野虎丸王座。前年的第44期名人戰七番棋,對決雙方張栩九段當時是名人,而芝野虎丸王座是?挑戰者。
這個時候研究室的話題是決定先后手的猜先。通常情況下接受挑戰的棋手會拿10~20顆白棋,而挑戰者會拿出1~2顆黑棋,猜白棋是奇數還是偶數。如果猜對的話,挑戰者執黑,猜錯的話將會執白。
挑戰者通常情況下會拿1顆子,?張栩說:“以前自己很想拿黑棋,所以就一直把如何剛好拿10顆白棋當作練習在玩”?。在知道了棋子的重量和感覺之后,有8成情況可以準確拿出10顆白子。這一天張栩也進行了挑戰,只可惜拿了9顆子?。然后芝野虎丸也試著嘗試了這個游戲,研究室在一片祥和的氣氛中進行。
?10:00
本以為是非常穩健的開局
本以為這盤棋會是非常穩健的開局,但是?井山裕太的白22非常少見。正常情況下白A之后行至黑F完成定式。實戰白22這手棋,如果沒有白16這顆子的話將會下成AI發明的大型定式,?實戰白16這顆子的位置,在研究室里引發了爭論。
這顆子是不是離黑棋太近了,還是進攻黑棋時絕佳的選點。
井山裕太的趣向,讓這盤棋早早地進入了未知的?世界。
?11:00
挑戰者的黑23
一力遼的黑23,張栩表示?:“好聽一點就是穩健,不好聽就是消極的一手棋”。
都是喜歡戰斗的兩位棋手,但是在布局階段讓人有一種“可能會是一盤漫長的持久戰”?。
?12:00
進入午休
一力遼在考慮第51手的時候,時間來到了正午進入了午休?。雙方的用時,每方8小時的保留時間?,執黑的一力遼1小時32分,執白的井山裕太1小時28分。對局在下午1時繼續。
?12:00
午餐是蕎麥面vs意面
井山裕太的午餐是“熱蕎麥面”?和烏龍茶。材料有樸蕈和裙帶菜以及蔥花?。湯汁微甜,可以說是比較奢侈的?味道。
一力遼挑戰者點的是“番茄海鮮意面”和橙汁?。不僅有大蝦,還有海螺等豐盛的海鮮食材,還有濃厚的番茄醬以及手打意面。
上星期的碁圣戰第4局中,一力遼點了冷制意面和牛排?。這一次一力遼選擇了較為簡單的料理。
?12:00
雙方都在鞏固軍心
右下角的AI定式時候,黑33的小飛非常少見?。張栩說:“這里如果不研究的話,是很難下出手的”?。行至黑39?壓迫右下角的白棋,黑棋豪爽的在外圍筑成了外勢。
白44是井山裕太的獨特靈感。面對黑棋的外勢選擇大膽作戰?。張栩說:“本以為會下出一手比較普通的棋,但是這手棋我完全沒想到”。一力遼繼續在左下角黑45開始鞏固外勢。白44這顆子看上去有些沒有底氣?。再加上這個時候還輪到黑棋行棋。?這盤棋早早地迎來了勝負處。?相信在午休的時候,雙方的腦海里也在反復計算著局面。
13:00
對局繼續
下午1時,對局繼續。?一力遼沒有立馬下出第51手,抱著手臂考慮著局面。而井山裕太則脫掉了外套。
13?:20
井山裕太停了下來
午休過后,一力遼下出了?富有創造力的一手棋。
那是研究室完全沒有想到的▲?。看上去滿是漏洞的一手棋,其實瞄著遙遠的左下角白棋。研究室里張栩和芝野虎丸都連呼“有點厲害”?。這幾年,經常下出一些驚人手段的一力遼,在名人戰的大舞臺也堅持?大膽創意。?井山裕太或許也沒有想到這手棋,停了下來。
14:30
一力遼,自信的粘
午休過后的第一手棋,一力遼?大膽地下在了黑1,井山裕太考慮了30分鐘后下在白2。張栩說:“稍微妥協了”?。本來白2這手棋想要在左下角小飛一手,但是?沖斷的話將會是非常復雜的變化。即便面對強手,職業棋手都想用?更強勢的手段予以回敬,但是井山裕太收斂了一些。
黑3開始從左邊到中央的模樣非常壯觀,井山裕太從白4開始在黑棋中腹動出?。但是一力遼不慌不忙,選擇黑5的粘上。研究室發出了“自信的一手棋”的感嘆,但是最強AI“絕藝”的勝率從黑60%降到了黑45%?。?張栩說:“對局者拼命想到的一手棋,但是AI很快就給出一個勝率,對對局者來說是非常難受的時代”。?面對井山裕太的白6,一力遼的下一手棋依然以強手回應。
?14:50
正式開始戰斗
面對黑棋強大的外勢,白棋3子浮在空中?,挑戰者在這個時候選擇直接動手。
那就是黑57的點。黑棋直接進攻了白棋撿漏的防線,井山裕太再一次停了下來。這盤棋可以看出一力遼的積極作戰。這盤棋也就此開始了戰斗。
15:00
一力遼不吃蛋糕
下午3時,點心時間。井山裕太點了水果拼盤和冰檸檬紅茶?。水果拼盤里有哈密瓜、桃子和西瓜等,?裝盤漂亮的一道料理。
而一力遼就點了一杯咖啡。東京椿山莊酒店的負責人表示,當初一力遼點了蛋糕,但是因為“離席吃東西太浪費時間”,就取消了蛋糕。
為了防止疫情傳染,雙方的點心都搬到了各自的休息室里,必須要離開對局室才能吃東西?。雖然這個時候,一力遼剛剛在白棋薄弱的防線里丟下了一子?。但是一力遼不想浪費一分一秒?,想要集中精力在這盤棋上面。
15:50
井山裕太也不吃點心
下午3時,井山裕太的水果拼盤早已搬到了休息室,但是酒店的工作人員表示,過了50分鐘井山裕太依然沒有來到休息室,?水果拼盤碰都沒碰。對局者已經?全身心投入到棋局中,可見局面已經兇險到何等程度。
?16:00
雙方均勢
下午4時,雙方的用時是井山裕太3小時07分,?一力遼2小時53分。雙方在用時上?沒拉開差距。左邊的戰斗本以為會是?針尖麥芒,但是有可能會和平收場。最強AI“絕藝”表示勝率是井山裕太的60%?。?從人類來看,這盤棋的局勢也差不多兩分。
17:00
準備封手
下午5時,距離封手還有1個小時,根據規定,在下午6時的時候,行棋一方?需要對下一手棋進行封手。
但是時間到了5點半,行棋一方可以立馬選擇封手。從這里開始雙方朝著封手展開攻防。
棋局行至第73手,AI的評價是黑5.9%,白94.1%。
17?:05
陷入困惑的一力遼
AI的勝率,立馬就傾向于?井山裕太。
一力遼在▲落子之后?,朝著孤立的白棋3子展開進攻,但是最終無功而返。從▲開始,就像牛若丸一樣地一一躲過黑棋的進攻。?黑12落子之后,AI的勝率立馬從34%跌至7%。這是為什么呢?張栩認為,下到黑16形成的目數,可以說下方黑棋的銅墻鐵壁完全沒有派上用處。
銅墻鐵壁在對方的進攻中發揮長處,但是▲?的進攻,最終黑棋2子反而被白棋吃掉。組邊的一團白棋,?在黑棋沒有任何獲利的情況下就基本安定。
17:32
一力遼選擇封手
下午5時32分,一力遼在考慮第77手的時候示意封手。前往其他房間,在封手紙寫下了封手后,裝入信封?交給了立會人張栩。雙方的用時,執黑的一力遼3小時50分,執白的井山裕太3小時42分。
?比賽將在8月27日上午9時繼續。
18:00
張栩和芝野虎丸的解說?
下午6時,立會人張栩和擔任本報解說的芝野虎丸都來到了?YouTube頻道,對第一天的棋局進行回顧,并預測了封手。
?針對下午左邊展開的攻防戰,張栩表示:“每一手棋都很難預測,都是充滿了想法的手段”,但是從結果來看,黑棋并沒有發揮左下角到下方形成的厚勢?。表示:“棋型效率很低”。
?關心的是一力遼的封手。
兩位棋手都預測下一手棋都是A位小飛,從還沒有戰斗的上方?開始作戰,然后展開攻勢。
芝野虎丸表示?:“白棋稍好”,但是張栩補充說:“一力遼是不會束手無措就這樣簡單輸掉的棋手”?。期待一力遼在第二天的頑強作戰。
子 發自 凹非寺 量子位 報道 | 公眾號 QbitAI
常常發資源的英偉達工程師小姐姐Chip Huyen,又發射了一套Python隱藏功能合集。
里面都是她“從前沒發現,或者從前不太敢用”的機器學習技巧,有notebook可以直接跑。
合集名叫python-is-cool,推特宣布之后不到半天,已經收獲了2400+贊。
那么,這份令人奔走相告的資源,到底長什么樣子?
就像開頭提到的:這里的功能,要么是小姐姐花了很久才找到的,要么是曾經讓她瑟瑟發抖到不敢嘗試的。
不過現在,她的技巧已經成功支配了這些功能,于是分享了出來。
目前一共有5個版塊,專注機器學習,日后還會持續更新:
1、Lambda、Map、Filter、Reduce函數
lambda 關鍵字,是用來創建內聯函數 (Inline Functions) 的。square_fn 和 square_ld 函數,在這里是一樣的。
1def square_fn(x): 2 return x * x 3 4square_ld=lambda x : x * x 5 6for i in range(10): 7 assert square_fn(i)==square_ld(i)
lambda 函數可以快速聲明,所以拿來當回調 (Callbacks) 函數是非常理想的:就是作為參數 (Arguments) 傳遞給其他函數用的,那種函數。
和 map、filter 和 reduce 這樣的函數搭配使用,尤其有效。
map(fn,iterable) 會把 fn 應用在 iterable 的所有元素上,返回一個map object。
1nums=[1/3, 333/7, 2323/2230, 40/34, 2/3] 2nums_squared=[num * num for num in nums] 3print(nums_squared) 4 5==> [0.1111111, 2263.04081632, 1.085147, 1.384083, 0.44444444]
這樣調用,跟用有回調函數的 map 來調用,是一樣的。
1nums_squared_1=map(square_fn, nums) 2nums_squared_2=map(lambda x : x * x, nums) 3print(list(nums_squared_1)) 4 5==> [0.1111111, 2263.04081632, 1.085147, 1.384083, 0.44444444]
map 也可以有不止一個 iterable。
比如,你要想計算一個簡單線性函數 f(x)=ax+b 的均方誤差 (MSE) ,兩種方法就是等同的。
1a, b=3, -0.5 2xs=[2, 3, 4, 5] 3labels=[6.4, 8.9, 10.9, 15.3] 4 5# Method 1: using a loop 6errors=[] 7for i, x in enumerate(xs): 8 errors.append((a * x + b - labels[i]) ** 2) 9result1=sum(errors) ** 0.5 / len(xs) 10 11# Method 2: using map 12diffs=map(lambda x, y: (a * x + b - y) ** 2, xs, labels) 13result2=sum(diffs) ** 0.5 / len(xs) 14 15print(result1, result2) 16 17==> 0.35089172119045514 0.35089172119045514
要注意的是,map 和 filter 返回的是迭代器 (Iterator) ,這就是說它們的值不是存儲的,是按需生成的。
當你調用了sum(diffs) 之后,diffs 就空了。如果你想要保留 diffs 里面所有的元素,就用 list(diffs) 把它轉換成一個列表。
filter(fn,iterable) 也是和 map 一樣道理,只不過 fn 返回的是一個布爾值,filter 返回的是,iterable 里面所有 fn 返回True的元素。
1bad_preds=filter(lambda x: x > 0.5, errors) 2print(list(bad_preds)) 3 4==> [0.8100000000000006, 0.6400000000000011]
reduce(fn,iterable,initializer) 是用來給列表里的所有元素,迭代地應用某一個算子。比如,想要算出列表里所有元素的乘積:
1product=1 2for num in nums: 3 product *=num 4print(product) 5 6==> 12.95564683272412
上面這串代碼,和下面這串代碼是等同的:
1from functools import reduce 2product=reduce(lambda x, y: x * y, nums) 3print(product) 4 5==> 12.95564683272412
2、列表操作
小姐姐說,Python的列表太炫酷了。
2.1、解包 (Unpacking)
想把一個列表解包成一個一個元素,就這樣:
1elems=[1, 2, 3, 4] 2a, b, c, d=elems 3print(a, b, c, d) 4 5==> 1 2 3 4
也可以這樣:
1elems=[1, 2, 3, 4] 2a, b, c, d=elems 3print(a, b, c, d) 4 5==> 1 2 3 4
2.2、切片 (Slicing)
大家可能知道,如果想把一個列表反過來排,就用 [::-1] 。
1elems=list(range(10)) 2print(elems) 3 4==> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 5 6print(elems[::-1]) 7 8==> [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
而 [x:y:z] 這種語法的意思是,從索引x到索引y,每z個元素取一個。
如果z是負數,就是反向取了。
如果x不特別指定,就默認是在遍歷列表的方向上,遇到的第一個元素。
如果y不特別指定,就默認是列表最后一個元素。
所以,我們要從一個列表里面,每兩個取一個的話,就是 [::2] 。
1evens=elems[::2] 2print(evens) 3 4reversed_evens=elems[-2::-2] 5print(reversed_evens) 6 7==> [0, 2, 4, 6, 8] 8 [8, 6, 4, 2, 0]
也可以用這種方法,把一個列表里的偶數都刪掉,只留奇數:
1del elems[::2] 2print(elems) 3 4==> [1, 3, 5, 7, 9]
2.3、插入 (Insertion)
把列表里的其中一個元素的值,換成另一個值。
1elems=list(range(10)) 2elems[1]=10 3print(elems) 4 5==> [0, 10, 2, 3, 4, 5, 6, 7, 8, 9]
如果想把某個索引處的一個元素,替換成多個元素,比如把 1 換成 20, 30, 40 :
1elems=list(range(10)) 2elems[1:2]=[20, 30, 40] 3print(elems) 4 5==> [0, 20, 30, 40, 2, 3, 4, 5, 6, 7, 8, 9]
如果想把3個值 0.2, 0.3, 0.5 插在索引0和索引1之間:
1elems=list(range(10)) 2elems[1:1]=[0.2, 0.3, 0.5] 3print(elems) 4 5==> [0, 0.2, 0.3, 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2.4、拉平 (Flattening)
如果,一個列表里的每個元素都是個列表,可以用sum把它拉平:
1list_of_lists=[[1], [2, 3], [4, 5, 6]] 2sum(list_of_lists, []) 3 4==> [1, 2, 3, 4, 5, 6]
如果是嵌套列表 (Nested List) 的話,就可以用遞歸的方法把它拉平。這也是lambda函數又一種優美的使用方法:在創建函數的同一行,就能用上這個函數。
1nested_lists=[[1, 2], [[3, 4], [5, 6], [[7, 8], [9, 10], [[11, [12, 13]]]]]] 2flatten=lambda x: [y for l in x for y in flatten(l)] if type(x) is list else [x] 3flatten(nested_lists) 4 5# This line of code is from 6# https://github.com/sahands/python-by-example/blob/master/python-by-example.rst#flattening-lists
2.5、列表vs生成器
要想知道列表和生成器的區別在哪,看個例子:從token列表里面創建n-grams。
一種方法是用滑窗來創建:
1tokens=['i', 'want', 'to', 'go', 'to', 'school'] 2 3def ngrams(tokens, n): 4 length=len(tokens) 5 grams=[] 6 for i in range(length - n + 1): 7 grams.append(tokens[i:i+n]) 8 return grams 9 10print(ngrams(tokens, 3)) 11 12==> [['i', 'want', 'to'], 13 ['want', 'to', 'go'], 14 ['to', 'go', 'to'], 15 ['go', 'to', 'school']]
上面這個例子,是需要把所有n-gram同時儲存起來的。如果文本里有m個token,內存需求就是 O(nm) 。m值太大的話,存儲就可能成問題。
所以,不一定要用一個列表儲存所有n-gram。可以用一個生成器,在收到指令的時候,生成下一個n-gram,這叫做惰性計算 (Lazy Evaluation) 。
只要讓 ngrams 函數,用 yield 關鍵字返回一個生成器,然后內存需求就變成 O(n) 了。
1def ngrams(tokens, n): 2 length=len(tokens) 3 for i in range(length - n + 1): 4 yield tokens[i:i+n] 5 6ngrams_generator=ngrams(tokens, 3) 7print(ngrams_generator) 8 9==> <generator object ngrams at 0x1069b26d0> 10 11for ngram in ngrams_generator: 12 print(ngram) 13 14==> ['i', 'want', 'to'] 15 ['want', 'to', 'go'] 16 ['to', 'go', 'to'] 17 ['go', 'to', 'school']
還有一種生成n-grams的方法,是用切片來創建列表:[0, 1, …, -n], [1, 2, …, -n+1], …, [n-1, n, …, -1],然后把它們zip到一起。
1def ngrams(tokens, n): 2 length=len(tokens) 3 slices=(tokens[i:length-n+i+1] for i in range(n)) 4 return zip(*slices) 5 6ngrams_generator=ngrams(tokens, 3) 7print(ngrams_generator) 8 9==> <zip object at 0x1069a7dc8> # zip objects are generators 10 11for ngram in ngrams_generator: 12 print(ngram) 13 14==> ('i', 'want', 'to') 15 ('want', 'to', 'go') 16 ('to', 'go', 'to') 17 ('go', 'to', 'school')
注意,創建切片用的是 (tokens[…] for i in range(n)) ,不是 [tokens[…] for i in range(n)] 。
[] 返回的是列表,() 返回的是生成器。
3、類,以及魔術方法
在Python里面,魔術方法 (Magic Methods) 是用雙下劃線,作為前綴后綴的。
其中,最知名的可能就是 _init_ 了。
1class Node: 2 """ A struct to denote the node of a binary tree. 3 It contains a value and pointers to left and right children. 4 """ 5 def __init__(self, value, left=None, right=None): 6 self.value=value 7 self.left=left 8 self.right=right
不過,如果想輸出 (Print) 一個節點 (Node) ,就不是很容易了。
1root=Node(5) 2print(root) # <__main__.Node object at 0x1069c4518>
理想情況,應該是輸出它的值,如果它有子節點的話,也輸出子節點的值。
所以,要用魔術方法 _repr_ ,它必須返回一個可輸出的object,如字符串。
1class Node: 2 """ A struct to denote the node of a binary tree. 3 It contains a value and pointers to left and right children. 4 """ 5 def __init__(self, value, left=None, right=None): 6 self.value=value 7 self.left=left 8 self.right=right 9 10 def __repr__(self): 11 strings=[f'value: {self.value}'] 12 strings.append(f'left: {self.left.value}' if self.left else 'left: None') 13 strings.append(f'right: {self.right.value}' if self.right else 'right: None') 14 return ', '.join(strings) 15 16left=Node(4) 17root=Node(5, left) 18print(root) # value: 5, left: 4, right: None
如果想對比兩個節點 (的各種值) ,就用 _eq_ 來重載==運算符,用 _lt_ 來重載 < 運算符,用 _ge_ 來重載 >=。
1class Node: 2 """ A struct to denote the node of a binary tree. 3 It contains a value and pointers to left and right children. 4 """ 5 def __init__(self, value, left=None, right=None): 6 self.value=value 7 self.left=left 8 self.right=right 9 10 def __eq__(self, other): 11 return self.value==other.value 12 13 def __lt__(self, other): 14 return self.value < other.value 15 16 def __ge__(self, other): 17 return self.value >=other.value 18 19 20left=Node(4) 21root=Node(5, left) 22print(left==root) # False 23print(left < root) # True 24print(left >=root) # False
想要了解更多魔術方法,請前往:
https://www.tutorialsteacher.com/python/magic-methods-in-python
或者使用官方文檔,只是有一點點難讀:
https://docs.python.org/3/reference/datamodel.html#special-method-names
這里,還要重點安利幾種魔術方法:
一是 _len_ :重載 len() 函數用的。
二是 _str_:重載 str() 函數用的。
三是 _iter_:想讓object變成迭代器,就用這個。有了它,還可以在object上調用 next() 函數。
對于像節點這樣的類,我們已經知道了它支持的所有屬性 (Attributes) :value、left和right,那就可以用 _slots_ 來表示這些值。這樣有助于提升性能,節省內存。
1class Node: 2 """ A struct to denote the node of a binary tree. 3 It contains a value and pointers to left and right children. 4 """ 5 __slots__=('value', 'left', 'right') 6 def __init__(self, value, left=None, right=None): 7 self.value=value 8 self.left=left 9 self.right=right
想要全面了解 _slots_ 的優點和缺點,可以看看Aaron Hall的精彩回答:
https://stackoverflow.com/a/28059785/5029595
4、局部命名空間,對象的屬性
locals() 函數,返回的是一個字典 (Dictionary) ,它包含了局部命名空間 (Local Namespace) 里定義的變量。
1class Model1: 2 def __init__(self, hidden_size=100, num_layers=3, learning_rate=3e-4): 3 print(locals()) 4 self.hidden_size=hidden_size 5 self.num_layers=num_layers 6 self.learning_rate=learning_rate 7 8model1=Model1() 9 10==> {'learning_rate': 0.0003, 'num_layers': 3, 'hidden_size': 100, 'self': <__main__.Model1 object at 0x1069b1470>}
一個object的所有屬性,都存在 _dict_ 里面。
1print(model1.__dict__) 2 3==> {'hidden_size': 100, 'num_layers': 3, 'learning_rate': 0.0003}
注意,當參數列表 (List of Arguments) 很大的時候,手動把每個參數值分配給一個屬性會很累。
想簡單一點的話,可以直接把整個參數列表分配給 _dict_ 。
1class Model2: 2 def __init__(self, hidden_size=100, num_layers=3, learning_rate=3e-4): 3 params=locals() 4 del params['self'] 5 self.__dict__=params 6 7model2=Model2() 8print(model2.__dict__) 9 10==> {'learning_rate': 0.0003, 'num_layers': 3, 'hidden_size': 100}
當object是用 kwargs** 初始化的時候,這種做法尤其方便 (雖然 kwargs** 還是盡量少用為好) :
1class Model3: 2 def __init__(self, **kwargs): 3 self.__dict__=kwargs 4 5model3=Model3(hidden_size=100, num_layers=3, learning_rate=3e-4) 6print(model3.__dict__) 7 8==> {'hidden_size': 100, 'num_layers': 3, 'learning_rate': 0.0003}
前4個版塊就到這里了,至于第5個版塊傳授了怎樣的技巧,先不介紹,大家可以從傳送門前往觀察:
https://github.com/chiphuyen/python-is-cool
貢獻資源的Chip Huyen小姐姐,現在是英偉達的高級深度學習工程師了。
但在2015年進入斯坦福讀書之前,她還是個沒接觸過深度學習的作家,旅行路上的故事已經出版了兩本書。
△ 對,是個越南小姐姐
原本想讀英文專業,卻在選了一門計算機課之后,走上了深度學習的不歸路。
畢業前,她在Netflix實習過;畢業后,她在斯坦福教過TensorFlow,課號CS20;一年前離開學校,進入英偉達。
正式選擇了機器學習的她,依然像旅行的時候一樣,喜歡和大家分享經歷。
這位小姐姐產出的各式資源和感悟,量子位也介紹過不止一次。
爬網頁、洗數據、創建海量數據集一條龍:
https://mp.weixin.qq.com/s/rOXKglzYLRqTJkyLEZqJ6A
免費機器學習課程,從概率統計到全棧深度學習:
https://mp.weixin.qq.com/s/Jk8YuQuP5e64Q0ak-WJUKg
AI從業者要不要讀博,要不要自己創業:
https://mp.weixin.qq.com/s/MTpS6RwCTLIxwP8iDbZotQ
加上今天的Python隱藏技巧,(至少) 是第四次了:
如果你想更順滑地使用Python,快馬克這些方法吧。
項目傳送門:
https://github.com/chiphuyen/python-is-cool
Notebook傳送門:
https://github.com/chiphuyen/python-is-cool/blob/master/cool-python-tips.ipynb
— 完 —
誠摯招聘
量子位正在招募編輯/記者,工作地點在北京中關村。期待有才氣、有熱情的同學加入我們!相關細節,請在量子位公眾號(QbitAI)對話界面,回復“招聘”兩個字。
量子位 QbitAI · 頭條號簽約作者
?'?' ? 追蹤AI技術和產品新動態
*請認真填寫需求信息,我們會在24小時內與您取得聯系。