天天看點

Python大佬 | 菜鳥進階必備的九大技能!

Python是一種很棒的語言,文法簡單,無需在代碼中搜尋分号。對于初學者來說,Python是入門最簡單的語言之一。Python有大量的庫支援,你還可以安裝其他庫來增加自己的程式設計經驗。

學了一陣子之後,你可能會覺得:為如此簡單的操作寫大量的代碼有些令人困惑。實際上,事情并沒有你想得那麼糟。了解其背後的邏輯比寫幾行代碼更為重要。短代碼更好,但如果邏輯有問題,那麼無論如何你的代碼都會有問題。随着經驗和創造力的增長,最終你的代碼将會變得更短、更好。

初學者與中級程式員

那麼,對于Python程式員而言,初學者和進階者有什麼差別呢?

本文将重點介紹以下方面:

  • 解決問題和提出問題;
  • XY問題;
  • 了解代碼為何起作用(或不起作用);
  • 使用字元串;
  • 使用清單;
  • 使用循環;
  • 使用函數(并正确談論函數);
  • 面向對象程式設計;
  • 尊重PEP。

 解決問題和提出問題

程式員缺乏解決問題能力的話,代碼出色也是枉然。

如果你解決問題的思維不夠發達,可能就無法為你要解決的問題找到最佳的解決方案。程式設計不僅僅是編寫代碼,需要解決問題才能有機會出初學者行列。

提出程式設計相關的問題也很重要。如果不經嘗試,就讓别人解決你的問題,可能也會出局。這很難,但如果不嘗試自己解決問題,你将對解決方案一無所得。

如果想要了解更多關于程式設計提問的技能,我另有一篇文章,連結如下(英文):How to Ask Questions About Programming:https://medium.com/better-programming/how-to-ask-questions-about-programming-dcd948fcd2bd

XY問題

“我需要從字元串中提取最後3個字元。”

“不,你不需要。隻需檔案擴充名。”

 XY問題很有趣。你有個X問題,當你調用服務中心時,會尋求Y問題的解決方案,以解決X問題。

上面的案例就是極好的例子。如果想要檔案名中的檔案擴充名,很容易假設你需要的是最後3個字母。

如何寫代碼:

def extract_ext(filename):
    return filename[-3:]
print (extract_ext('photo_of_sasquatch.png'))
>>> png      

使用者從一開始應該會索要擴充名,最後3個字母是Y問題,而X問題是我們想要擴充名。

def extract_ext(filename):
    return filename.split('.')[-1]
print (extract_ext('photo_of_sasquatch.png'))
print (extract_ext('photo_of_lochness.jpeg'))
>>> png
>>> jpeg      

成功了!

你也可以使用标準庫 `os.path.splitext() `,點選這裡檢視:os.path.splitext():​​https://www.geeksforgeeks.org/python-os-path-splitext-method/​​

了解代碼為何起作用(或不起作用)

作為新手,你可能要花幾天來對付一小段代碼。如果這段代碼突然起作用了,你可能會感覺放心,然後繼續下一段代碼。這是最糟糕的事情之一。不了解原因隻管運作的做法,可能比不了解代碼的為什麼不運作更加危險。

不了解為何代碼不運作的情況總會發生,當進行故障排除并搞清楚其原因時,思考代碼不運作的原因和最終使其運作的因素非常重要。這次學到的知識會帶到下一個程式中。

例如,如果多個縮進級别的代碼中出現了縮進錯誤,可以嘗試随機調整代碼塊,然後在最終運作時為自己慶祝。

切記,在大多數IDE中,可以折疊循環和if語句,進而更容易檢視正在使用的部分。

Python大佬 | 菜鳥進階必備的九大技能!

右側是折疊了if/else語句的ATOM

另一種辦法是将你的代碼通過 www.pythontutor.com可視化,就可以逐行檢視代碼運作的方式了。

Python大佬 | 菜鳥進階必備的九大技能!

使用pythontutors執行代碼

使用字元串

這部分内容其實與字元串不完全相關,與挖掘Python優雅的庫有更大關系。

我們很早就在Python中學過,字元串也可以看作是一串字元。你也可以使用索引通路字元串中的字元。

word = 'supergreat'
print (f'{word[0]}') 
>>> s
print (f'{word[0:5]}')
>>> super      

敏銳的學習者會檢視`str()`所提供的内容,但也可以不檢視 `str()`文檔繼續程式設計。

檢視函數或過程文檔可以通過調用 `help(str)` 或者`dir(str)`來實作。執行此操作時,你可能會發現一些并不知道的方法,也許你在檢視`str()`時,找到有個名叫 `endswith()` 的方法,或許能用在某處。

Python大佬 | 菜鳥進階必備的九大技能!
Python大佬 | 菜鳥進階必備的九大技能!

下面是一些以兩種不同方式執行相同操作的代碼案例,一種用到了我們才談過的拆分,還有一種用到了我們剛剛學到的 `endswith()` :

filenames = ['lochness.png' , 'e.t.jpeg' , 'conspiracy_theories_CONFIRMED.zip']
# 1: Using ENDSWITH
for files in filenames:
    if files.endswith('zip'):
        print(f'{files} is a zip file')
    else:
        print (f'{files} is NOT a zip file')
# 2: Using SPLIT
for files in filenames:
    if files.split('.')[-1] == 'zip':
        print(f'{files} is a zip file (using split)')
    else:
        print (f'{files} is NOT a zip file (using split)')      

大多程式員是從來不會把所有文檔讀遍來學習全部内容的。作為一名程式員,部分工作就是要搜尋如何解決問題的資訊。 

使用清單

清單很棒,用途也很廣泛。

下面的案例中,我們将整數和字元串混合在了一起:

my_list = ['a' , 'b' , 'n' , 'x' , 1 , 2 , 3, 'a' , 'n' , 'b']
for item in my_list:
    print (f'current item: {item}, Type: {type(item)}')      
Python大佬 | 菜鳥進階必備的九大技能!

注意我們是怎麼将字元串和整數混合在一起的,如果嘗試對其排序,就會報錯:

print (my_list.sort())      
Python大佬 | 菜鳥進階必備的九大技能!

如果我們想把整數與字母分開要怎麼做?一種方式是通過循環來實作,我們可以周遊清單中的所有項目。初學者很早就會使用循環了,循環對于程式設計也很重要。

代碼可能是下面這樣的:

my_list = ['a' , 'b' , 'n' , 'x' , 1 , 2 , 3 , 'a' , 33.3 , 'n' , 'b']
number_list = []
string_list = []
for item in my_list:
    print (f'current item: {item}, Type: {type(item)}')
    if not isinstance(item,str):
        number_list.append(item)
    else:
        string_list.append(item)
my_list = string_list      

即便有些混亂,這也是一種有效的方式,可以運作,不過經過重構可以用單行來表示!

如果想要生活多些樂趣,請學習Python的清單解析式下面是同樣問題通過清單解析式得出的:

my_list = [letter for letter in my_list if isinstance(letter,str)]      

就是這樣!

還沒結束!使用過濾器也可以獲得同樣的結果:

def get_numbers(input_char):
    if not isinstance(input_char,str):
        return True
    return False


my_list = [1,2,3,'a','b','c']
check_list = filter(get_numbers, my_list)
for items in check_list:
    print(items)      
Python大佬 | 菜鳥進階必備的九大技能!

現在你可能明白了,實作同樣的結果有很多方法,你必須找出适合你或你團隊的那個。

額外知識點

  • 反向清單(或字元串): 
names = ['First' , 'Middle' , 'Last']
print(names[::-1])
>>> ['Last', 'Middle', 'First']      
  • 在清單中加入元素:
names = ['First' , 'Middle' , 'Last']
full_name = ' '.join(names)
print(f'Full Name:\n{full_name}')
>>> First Middle Last6. 使用循環:      

是否在Python中見過這樣的代碼?

greek_gods = ['Zeus' , 'Hera' , 'Poseidon' , 'Apollo' , 'Bob']
for index in range(0,len(greek_gods)):
    print (f'at index {index} , we have : {greek_gods[index]}')      

你可能發現了,它來自其他語言,這不是Python的風格。在Python中,你可以使用for-each循環:

for name in greek_gods:
    print (f'Greek God: {name}')      

你很快就能發現,這裡我們不包含索引。如果想用索引列印要怎麼做?在Python中,你可以使用枚舉(enumerate參數),這是一種通路所需内容的絕佳方案。

for index, name in enumerate(greek_gods):
    print (f'at index {index} , we have : {name}')      
Python大佬 | 菜鳥進階必備的九大技能!

使用函數(并正确談論函數)

我在從事動畫工作時,總是說如果同一個操作重複5次,就應該考慮是否需要寫個程式。有些時候花上兩周開發一款工具可以節省你六個禮拜的工作時間。

編寫代碼時,如果發現同一動作執行了不止一次,應該考慮這是過程還是函數,還不隻是寫寫代碼。函數會傳回内容,過程則隻是運作代碼,第一個案例是個過程,第二個是函數。

這樣說可能會令人困惑,下面是其工作原理的示意圖: 

Python大佬 | 菜鳥進階必備的九大技能!

注意print和return的差異,看起來也許很相似,但如果你檢視輸出結果,函數隻會傳回發送的名稱。

下一個要了解的文法是parameters和arguments,在過程或函數中定義時(紅色部分)被稱為形參(parameters),當發送名稱到過程或函數中(綠色部分)時就叫實參(arguments)了。

下面是些案例:

案例1

def print_list(input_list):
    for each in input_list:
        print(f'{each}')
    print() #just to separate output
greek_gods = ['Zeus' , 'Hera' , 'Poseidon' , 'Apollo' , 'Bob']
grocery_list = ['Apples' , 'Milk' , 'Bread']
print_list(greek_gods)
print_list(grocery_list)
print_list(['a' , 'b' , 'c'])      
Python大佬 | 菜鳥進階必備的九大技能!

無需把循環寫上3次,隻需在過程中寫上一次,然後在需要時調用即可。在案例2中,你可以發現代碼是如何傳回反向清單的。

案例2​

def reverse_list(list_input):
    return list_input[::-1]
my_list = ['a', 'b' , 'c']
print (reverse_list(my_list))
>>> ['c', 'b', 'a']      

面向對象程式設計

Python是一種面向對象的語言,其強大之處在于對象。将對象視為藍圖,如果使用藍圖,你可以建立該藍圖的執行個體。也就是說,你可以建立需要的多個藍圖執行個體,但不會損毀你使用的藍圖。

面向對象程式設計(OOP)是一個龐大的話題,是以我們不會在本節中涵蓋所有你需要了解的内容,但可以通過幾個簡單的示例幫你入門。

如果你之前讀過面向對象程式設計的相關内容,可能已經厭倦了學生(student)類,但我們又來了。從定義一個名為student的類開始,student會擁有一個名稱和一個subject_list:

class Student():
    def __init__(self,name):
        self._name = name
        self._subject_list = []      
如果想要建立一個student,可以像這樣将其配置設定給變量:student1 = Student('Martin Aaberge')如果需要更多student,可以使用同一個類并添加另外的姓名:
student2 = Student('Ninja Henderson')`student1`和`student2`都是student類的執行個體,它們共享同一個藍圖,但彼此之間并無關系。此時,我們對學生們能做的不多,但我們确實增加了一個主題清單。要填充此清單,我們需要建立方法,你可以調用方法來實作與該類執行個體的互動。我們更新:class Student():
    def __init__(self,name):
        self._name = name
        self._subject_list = []
    def add_subject(self, subject_name):
        self._subject_list.append(subject_name)
    def get_student_data(self):
        print (f'Student: {self._name} is assigned to:')
        for subject in self._subject_list:
            print (f'{subject}')
        print()
        這個類可以用于建立、編輯學生資訊,并擷取我們存在其中的資訊:#create students:
student1 = Student('Martin Aaberge')
student2 = Student('Heidi Hummelvold')
#add subjects to student1
student1.add_subject('psychology_101')
student1.add_subject('it_security_101')
#add subject to student2
student2.add_subject('leadership_101')
#print current data on students
student1.get_student_data()
student2.get_student_data()      

将類儲存在單獨的檔案中并導入主代碼的操作很常見,在我們的案例中,我們會在student.py檔案中建立一個`student`類,并将其導入我們的main.py檔案(本案例中,它們都位于同一個檔案夾中)。

from student import Student
student1 = Student('Martin')
student1.add_subject('biomechanics_2020')
student1.get_student_data()      
Python大佬 | 菜鳥進階必備的九大技能!

student類和main.py在使用它      

Python大佬 | 菜鳥進階必備的九大技能!

尊重PEP

我們經常看到人們在寫Python代碼時并不尊重PEP(Python增強提案:Python Enhancement Proposals),但我自己會尊重。

當你在開發環境中工作時,遵守标準非常重要——如果不是PEP标準,也至少要遵守公司的标準。

PEP是代碼的一組準則,下面是PEP-8的連結(https://www.python.org/dev/peps/pep-0008/),讀起來很棒。請確定你通讀過一次,了解大概内容。一個典型的案例是`snake_case`,Python是以`snake_case`來寫的,這代表着我們用下劃線來區分詞組,即便大學裡也會犯錯,是以别難過,隻要别這樣做就行了。

這樣寫是對的: 

chocolate_cake = 'yummy'      

這樣是錯的:

chocolateCake = 'Yummy      

原文連結:

​​https://medium.com/better-programming/9-skills-that-separate-a-beginner-from-an-intermediate-python-programmer-8bbde735c246​​

本文僅做學術分享,如有侵權,請聯系删文。​