主頁 > 後端開發 > 寫好 Python 代碼的重要技巧

寫好 Python 代碼的重要技巧

2022-04-01 07:01:01 後端開發

如何才能寫好Python代碼?很多小伙伴都會問這樣的問題,今天這篇就來告訴大家怎樣寫好Python代碼,
在這里插入圖片描述

程式設計的好與壞,早在我們青蔥歲月時就接觸過了,只是那是并不知道這竟如此重要,能夠立即改善程式設計、寫出“好”代碼的知識有以下幾點:

?面向物件五個基本原則;

?常見的三種架構;

?繪圖;

?起一個好名字;

?優化嵌套的 if else 代碼;

當然,其他技術知識的豐富程度也決定了程式設計的好壞,例如通過引入訊息佇列解決雙端性能差異問題、通過增加快取層提高查詢效率等,下面我們一起來看看,上面列出的知識點包含哪些內容,這些內容對代碼和程式設計的改善有何幫助,

在這里插入圖片描述

面向物件五個基本原則

本書作者是 2010 級學生,面向物件是作者青蔥時期發展火熱的編程范式,它的五個基本原則是:

?單一職責原則;

?開放封閉原則;

?依賴倒置原則;

?介面隔離原則;

?合成復用原則;

下面我們將通過對比和場景假設的方式了解五個基本原則對代碼質量的影響,

立竿見影的單一職責原則

沒錯,立竿見影、效果卓越,對于我們這些自學編程無師自通的人來說,能把功能實作就可以了,根本沒有時間考慮代碼優化和維護成本問題,時光流逝,竟在接觸編程很長一段時間后才發現它竟如此重要,

俗話說只要代碼寫的夠爛,提升就足夠明顯,以一個從檔案內容中匹配關鍵資料并根據匹配結果發出網路請求的案例,看看大部分程式員的寫法:

####Python學習交流Q群:906715085####
import
re import requests FILE = "./information.fet" def extract(file): fil = open(file, "r") content = fil.read() fil.close() find_object = re.search(r"url=\d+", content) find = find_object.group(1) text = requests.get(find) return text if __name__ == "__main__": text = extract(FILE) print(text)

 

需求已經實作,這點毋庸置疑,但是問題來了:

?如果讀取檔案的時候發生例外了怎么辦?

?如果資料源發生變化該如何處理?

?如果網路請求回傳的資料不符合最終要求怎么辦?

如果你心里的第一個反應是改代碼,那你就要注意了,完成一件事中間的某個環節發生變化,改代碼是在所難免的,但是如果按照上面這種寫法,不僅代碼越改越亂,連邏輯也會越來越亂,單一職責原則表達的是讓一個函式盡量只做一件事,不要將多件事混雜在一個函式中,

上面的代碼如果重新設計,我認為至少應該是這樣的:

def get_source():   
 """獲取資料源"""    
 return

def extract_(val):  
  """匹配關鍵資料"""  
    return

def fetch(val):  
  """發出網路請求""" 
     return

def trim(val):  
  """修剪資料"""   
   return

def extract(file):  
  """提取目標資料"""  
    source = get_source()   
     content = extract_(source)    
     text = trim(fetch(content))   
      return text

if __name__ == "__main__":   
 text = extract(FILE)   
  print(text)

 

把原來放在一個函式中實作的多個步驟拆分成為多個更小的函式,每個函式只做一件事,當資料源發生變化時,只需要改動 get_source 相關的代碼即可;如果網路請求回傳的資料不符合最終要求,我們可以在 trim 函式中對它進行修剪,這樣一來,代碼應對變化的能力提高了許多,整個流程也變得更清晰易懂,

改動前后的變化如下圖所示:
在這里插入圖片描述

單一職責原則的核心是解耦和增強內聚力,如果一個函式承擔的職責過多,等于把這些職責耦合在一起,這種耦合會導致脆弱的設計,當發生變化時,原本的設計會遭受到意想不到的破壞,單一職責原則實際上是把一件事拆分成多個步驟,代碼修改造成的影響范圍很小,

讓代碼穩定性飛升的開放封閉原則和依賴倒置原則

開放封閉原則中的開放指的是對擴展開放,封閉指的是對修改封閉,需求總是變化的,業務方這個月讓你把資料存盤到 MySQL 資料庫中,下個月就有可能讓你匯出到 Excel 表格里,這時候你就得改代碼了,這個場景和上面的單一職責原則很相似,同樣面臨代碼改動,單一職責原則示例主要表達的是通過解耦降低改動的影響,這里主要表達的是通過對擴展開放、對修改封閉提高程式應對變化的能力和提高程式穩定性,

穩定這個詞如何理解呢?

較少的改動或者不改動即視為穩定,穩定意味著呼叫這個物件的其它代碼拿到的結果是可以確定的,整體是穩定的,

按照一般程式員的寫法,資料存盤的代碼大概是這樣的:

class MySQLSave:

    def __init__(self):    
        pass
        
    def insert(self):    
        pass
        
    def update(self):       
     pass

class Business:  
  def __init__(self):        
  pass
  
    def save(self):        
    saver = MySQLSave()      
      saver.insert()

 

功能是能夠實作的,這點毋庸置疑,來看看它如何應對變化,如果要更換存盤,那么就意味著需要改代碼,按照上面的代碼示例,有兩個選擇:

?重新寫一個存盤到 ExcelSave 的類;

?對 MySQLSave 類進行改動;

上面的兩種選擇,無論怎么選都會改動 2 個類,因為不僅存盤的類需要改動,呼叫處的代碼也需要更改,這樣一來,它們整體都是不穩定的,如果換一種實作方式,根據依賴倒置的設計指導可以輕松應對這個問題,

邊看代碼邊理解:

import abc

class Save(metaclass=abc.ABCMeta):   
 @abc.abstractmethod   
  def insert(self):      
    pass
    
    @abc.abstractmethod   
     def update(self):  
           pass


class MySQLSave(Save):

    def __init__(self):    
        self.classify = "mysql"     
           pass
    def insert(self):       
     pass
    def update(self):      
      pass

class Excel(Save):  
  def __init__(self):       
   self.classify = "excel"
    def insert(self):       
     pass
    def update(self):
    pass

class Business:  
  def __init__(self, saver):      
    self.saver = saver
    def insert(self):      
      self.saver.insert()
    def update(self):    
        self.saver.update()

if __name__ == "__main__":   
 mysql_saver = MySQLSave() 
    excel_saver = Excel()   
     business = Business(mysql_saver)

 

這里通過內置的 abc 實作了一個抽象基類,這個基類的目的是強制子類實作要求的方法,以達到子類功能統一,子類功能統一后,無論呼叫它的哪個子類,都是穩定的,不會出現呼叫方還需要修改方法名或者修改傳入引數的情況,

依賴倒置中的倒置,指的是依賴關系的倒置,之前的代碼是呼叫方 Business 依賴物件 MySQLSave,一旦物件 MySQLSave 需要被替換, Business 就需要改動,依賴倒置中的依賴指的是物件的依賴關系,之前依賴的是物體,如果改為后面這種依賴抽象的方式,情況就會扭轉過來:
在這里插入圖片描述

物體 Business 依賴抽象有一個好處:抽象穩定,相對于多變的物體來說,抽象更穩定,代碼改動前后的依賴關系發生了重大變化,之前呼叫方 Business 直接依賴于物體 MySQLSave,通過依賴倒置改造后 Busines 和 ExcelSave、 MySQLSave 全都依賴抽象,

這樣做的好處是如果需要更換存盤,只需要創建一個新的存盤物體,然后呼叫 Business 時傳遞進去即可,這樣可以不用改動 Business 的代碼,符合面向修改封閉、面向擴展開放的開放封閉原則;

依賴倒置的具體實作方式使用了一種叫做依賴注入的手段,實際上單純使用依賴注入、不使用依賴倒置也可以滿足開閉原則要求,感興趣的讀者不妨試一試,
在這里插入圖片描述

挑肥揀瘦的介面隔離原則

介面隔離原則中的介面指的是 Interface,而不是 Web 應用里面的 Restful 介面,但是在實際應用中可以將其抽象理解為相同的物件,介面隔離原則在設計層面看,跟單一職責原則的目的是一致的,介面隔離原則的指導思想是:

?呼叫方不應該依賴它不需要的介面;

?依賴關系應當建立在最小介面上;

這實際上是告訴我們要給介面減肥,過多功能的介面可以選用拆分的方式優化,舉個例子,現在為圖書館設計一個圖書的抽象類:

import abc

class Book(metaclass=abc.ABCMeta):  
  @abc.abstractmethod    
  def buy(self):        
  pass
    @abc.abstractmethod    
    def borrow(self):      
      pass
    @abc.abstractmethod   
     def shelf_off(self):     
        pass
    @abc.abstractmethod 
       def shelf_on(self):      
         pass

 

圖可以被購買、可以被借閱、可以下架、可以上架,這看起來并沒有什么問題,但這樣一來這個抽象只能提供給管理人員使用,用戶操作時需要再設定一個新的抽象類,因為你不可能讓用戶可以操縱圖書上下架,介面隔離原則推薦的做法是把圖書的上下架和圖書購買、借閱分成 2 個抽象類,管理端的圖書類繼承 2 個抽象類,用戶端的圖書類繼承 1 個抽象類,這么看起來是有點繞,不要慌,我們看圖理解:

在這里插入圖片描述

這樣是不是一下就看懂了,這個指導思想很重要,不僅能夠指導我們設計抽象介面,也能夠指導我們設計 Restful 介面,還能夠幫助我們發現現有介面存在的問題,從而設計出更合理的程式,

輕裝上陣的合成復用原則

合成復用原則的指導思想是:盡量使用物件組合,而不是繼承來達到復用的目的,合成復用的作用是降低物件之間的依賴,因為繼承是強依賴關系,無論子類使用到父類的哪幾個屬性,子類都需要完全擁有父類,合成采用另一種方式實作物件之間的關聯,降低依賴關系,

為什么推薦優先使用合成復用,而后考慮繼承呢?

因為繼承的強依賴關系,一旦被依賴的物件(父類)發生改變,那么依賴者(子類)也需要改變,合成復用則可以避免這樣的情況出現,要注意的是,推薦優先使用復用,但并不是拒絕使用繼承,該用的地方還得用,我們以一段代碼為例,說明合成復用和繼承的差異:

import abc


class Car:

    def move(self):        
    pass
    
    def engine(self): 
           pass

class KateCar(Car):

    def move(self):      
      pass
      
    def engine(self):  
          pass

class FluentCar(Car):

    def move(self):    
        pass
        
    def engine(self):     
       pass

 

這里的 Car 作為父類,擁有 move 和 engine 2 個重要屬性,這時候如果需要給汽車涂裝顏色,那么就要新增一個 color 屬性,3 個類都要增加,如果使用合成復用的方式,可以這么寫:

class Color:   
 pass

class KateCar:

    color = Color()
    
    def move(self):      
      pass
      
    def engine(self):     
       pass

class FluentCar:

    color = Color()
    
    def move(self):   
         pass
         
    def engine(self):       
     pass

 

類物件合成復用的具體操作是在類中實體化一個類物件,然后在需要的時候呼叫它,代碼可能沒有那么直觀,我們看圖:

在這里插入圖片描述

這個例子主要用于說明繼承和合成復用的具體實作方式和前后變化,對于 Car 的繼承無需深究,因為如果你執著地討論為什么右圖中的 2 個 Car 不用繼承,就會陷入牛角尖,

這里的合成復用選用的實作方式是在 2 個 Car 里面實體化另一個類 Color,其實也可以用依賴注入的手段在外部實體化 Color,然后把實體物件傳遞給 2 個 Car,

在這里插入圖片描述

常見的三種架構

了解多種不同的架構可以使我們的知識面更寬廣,面對一類問題的時候可以提出其它解決辦法,同時,了解多種架構可以讓我們在設計階段做好規劃,避免后續頻繁的重構,常見的三種架構分別是:

?單體架構;

?分布式架構;

?微服務架構;

單體架構

單體架構是我們平時接觸較多的架構,也是相對容易理解的架構,單體架構把所有功能都聚合在一個應用里,我們可以簡單地將這種架構視作:
在這里插入圖片描述

這種架構簡單、容易部署和測驗,大部分應用的初期都采用單體架構,單體架構也有幾個明顯缺點:

?復雜性高,所有功能糅合在一個應用里,模塊多、容易出現邊界模糊,而且隨著時間的推移和業務的發展,專案越來越大、代碼越來越多,整體服務效率逐漸下降;

?發布/部署頻率低,牽一發而動全身,新功能或問題修復的發布上線需要多方協調,發布時間一拖再拖,專案大則構建時間長、構建失敗的幾率也會有所增加;

?性能瓶頸明顯,一頭牛再厲害也抵不過多頭牛合力的效果,隨著資料量、請求并發的增加,讀性能的不足最先暴露出來,接著你就會發現其它方面也跟不上了;

?影響技術創新:單體架構通常選用一類語言或一類框架統一開發,想要引入新技識訓者接入現代化的服務是很困難的;

?可靠性低,一旦服務出現問題,影響是巨大的,

分布式架構

分布式架構相對于單體架構而言,通過拆分解決了單體架構面臨的大部分問題,例如性能瓶頸,假如單體架構是一頭牛,那么分布式架構就是多頭牛:
在這里插入圖片描述

當單體架構出現性能瓶頸時,團隊可以考慮將單體架構轉換為分布式架構,以增強服務能力,當然,分布式并不是萬能的,它解決了單體架構性能瓶頸、可靠性低的問題,但復雜性問題、技術創新問題和發布頻率低依然存在,這時候可以考慮微服務,

微服務架構

微服務架構的關鍵字是拆,將原本糅合在一個應用中的多個功能拆成多個小應用,這些小應用串聯起來組成一個與之前單體架構功能相同的完整應用,具體示意如下:
在這里插入圖片描述

每個微服務可以獨立運行,它們之間通過網路協議進行互動,每個微服務可以部署多個實體,這樣一來就具備了跟分布式架構相同的性能,單個服務的發布/部署對其它服務的影響較小,在代碼上沒有關聯,因此可以頻繁的發布新版本,復雜性的問題迎刃而解,拆分之后架構邏輯清晰、功能模塊職責單一,功能的增加和代碼的增加也不會影響到整體效率,服務獨立之后,專案就變得語言無關,評價服務可以用 Java 語言來實作也可以用 Golang 語言實作,不再受到語言或者框架的制約,技術創新問題得以緩解,

這是不是很像單一職責原則和介面隔離原則?

分布式和微服務并不是銀彈

從上面的對比來看,似乎分布式架構比單體架構好,微服務架構比分布式架構好,這么說來微服務架構>分布式架構>單體架構?

這么理解是不對的,架構需要根據場景和需求選擇,微服務架構和分布式架構看上去很美,但也衍生出了許多新問題,以微服務架構為例:

?運維成本高,在單體架構時,運維只需要保證 1 個應用正常運行即可,關注的可能只是硬體資源消耗問題,但如果換成微服務架構,應用的數量成百上千,當應用出現問題或者多應用之間協調例外時,運維人員的頭就會變大;

?分布式系統固有的復雜性,網路磁區、分布式事務、流量均衡對開發者和運維進行了敲打;

?介面調整成本高,一個介面的呼叫方可能有很多個,如果設計時沒有遵循開放封閉原則和介面隔離原則,那么調整的作業量會是非常大的;

?介面性能受限,原本通過函式呼叫的方式互動,在記憶體中很快就完成了,換成介面后通過網路進行互動,性能明顯下降;

?重復勞動,雖然有公共模塊,但如果語言無關且又要考慮性能(不用介面互動)就需要自己實作一份相同功能的代碼;

到呼叫哪種架構,需要根據具體的場景來選擇,如果你的系統復雜度并沒有那么高、性能追求也沒有那么高,例如一個日資料量只有幾萬的爬蟲應用,單體架構就足以解決問題,不需要強行做成分布式或者微服務,因為這樣只會增加自己的作業量,

畫好圖

在需要表達關系和邏輯梳理的場景里,圖永遠比代碼好,業內流行這么一句話“程式開發,設計先行”,說的是在開發前,需要對程式進行構思和設計,試想,如果連物件關系和邏輯都說不清楚,寫出的代碼會是好代碼嗎?

在這里插入圖片描述

在構思專案時可以使用用例圖挖掘需求和功能模塊;在架構設計時可以使用協作圖梳理模塊關系;在設計介面或者類物件時可以使用類圖做好互動計劃;在功能設計時可以使用狀態圖幫助我們挖掘功能屬性……

在這里插入圖片描述

了解繪圖的重要性之后,具體的繪圖方法和技巧可翻閱本書(《Python 編程參考》)的工程師繪圖指南章節展開學習,

起一個好名字

你還記得自己曾經起過的那些名字嗎:

reversalList
get_translation
get_data
do_trim
CarAbstract

 

起一個好的、合適的名字能夠讓代碼風格更統一,看上去清晰了然,起一個好名字不單單是單詞語法的問題,還會涉及風格選擇和用途,具體的命名方法和技巧可翻閱本書(《Python 編程參考》)的命名選擇與風格指南章節展開學習,

優化嵌套的 if else 代碼

寫代碼的時候用一些控制陳述句是很正常的事,但是如果 if else 嵌套太多,也是非常頭疼的,代碼看上去就像下面這樣,

在這里插入圖片描述

這種結構的產生是因為使用了 if 陳述句來進行先決條件的檢查,如果負責條件則進入下一行代碼,如果不符合則停止,既然這樣,那我們在先決條件的檢查上進行取反即可,代碼改動過后看起來像這樣:

if "http" not in url:       
 return
 if "www" not in url:       
  return

 

這是我平時常用的優化辦法,后來在張曄老師的付費專欄中看到這種手段的名稱——衛陳述句,\

當然,這種簡單的邏輯處理和 if else 控制流用衛陳述句進行處理是很有效的,但如果邏輯再復雜一些,用衛陳述句的效果就不見的那么好了,假設汽車 4S 店有折扣權限限制,普通銷售有權對 30 萬以內金額的汽車授予一定折扣,超過 30 萬但在 80 萬以內需要精英銷售進行授權,更高價格的車折扣需要店長授權,這個功能可以歸納為根據金額的大小來確定授權者,對應代碼如下:

def buying_car(price):   
 if price < 300000:      
   print("普通銷售")  
     elif price < 800000:        
     print("精英銷售")   
      elif price < 1500000:        
      print("店長")

 

代碼思路清晰,但存在的問題也明顯,如果以后擴展價格和定級,會增加更多的 if else 陳述句,代碼將變得臃腫,控制陳述句的順序是固定在代碼中的,如果想要調整順序,只能修改控制陳述句,

那么問題來了,有比 if else 更合適的辦法嗎?

這時候可以考慮一種叫做責任鏈的設計模式,責任鏈設計模式的定義為:為了避免請求發送者與多個請求處理者耦合在一起,于是將所有請求的處理者通過前一物件記住其下一個物件的參考而連成一條鏈;當有請求發生時,可將請求沿著這條鏈傳遞,直到有物件處理它為止,

看起來有點繞,我們通過代碼圖加深理解:

在這里插入圖片描述

處理類執行前根據先決條件判斷自身的 handler 是否能夠處理,如果不能則交給 next_handler,也就是責任鏈的下一個節點,上面的用責任鏈實作為:

class Manager:

    def __init__(self,):        
    self.obj = None
    
    def next_handler(self, obj):       
     self.obj = obj
     
    def handler(self, price):        
    pass
    

class General(Manager):

    def handler(self, price):       
     if price < 300000:            
     print("{} 普通銷售".format(price))       
      else:            
      self.obj.handler(price)
      

class Elite(Manager):

    def handler(self, price):       
     if 300000 <= price < 800000:           
      print("{} 精英銷售".format(price))       
       else:            
       self.obj.handler(price)

class BOSS(Manager):

    def handler(self, price):        
    if price >= 800000:            
    print("{} 店長".format(price))

 

創建好抽象類和具體的處理類之后,它們還沒有關聯關系,我們需要將它們掛載到一起,成為一個鏈條:

general = General()
elite = Elite()
boss = BOSS()
general.next_handler(elite)
elite.next_handler(boss)

 

這里建立的責任鏈順序為 General -> Elite -> BOSS,呼叫方只需要傳遞價格給 General,如果它沒有折扣的授予權它會交給 Elite 處理,如果 Elite 沒有折扣授予權則會交給 BOSS 處理,對應代碼如下:

prices = [550000, 220000, 1500000, 200000, 330000]    
for price in prices:       
 general.handler(price)  

 

這跟我們去 4S 店購車是一樣的,作為客戶,我們確定好要買的車即可,至于 4S 店如何申請折扣,誰來授權與我無關,我能拿到相應的折扣即可,

至此,if else 優化知識學習完畢,這一篇文章比較長,喜歡的點贊噢,不懂的留言評論,然后就是,下一篇見啦,

在這里插入圖片描述

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/453768.html

標籤:Python

上一篇:【代碼開源】GreaterWMS 抖音SDK呼叫教程

下一篇:2022DASCTF X SU 三月春季挑戰賽 Calc

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more