首頁  >  文章  >  後端開發  >  Python 3.7新功能數據class裝飾器詳解

Python 3.7新功能數據class裝飾器詳解

不言
不言原創
2018-04-21 14:44:591732瀏覽

這篇文章主要為大家介紹了關於Python 3.7新功能之dataclass裝飾器的相關資料,文中透過範例程式碼介紹的非常詳細,對大家的學習或工作具有一定的參考學習價值,需要的朋友們一起學習學習吧。

前言

Python 3.7 將於今年夏天發布,Python 3.7 中將會有許多新東西:

  • 各種字元集的改進

  • 對註解的延遲評估

  • 以及dataclass的支援


最令人興奮的新功能之一是dataclass 裝飾器。

什麼是Data Class

#大多數Python 開發人員寫過很多像下面這樣的類別:

class MyClass:
 def __init__(self, var_a, var_b):
 self.var_a = var_a
 self.var_b = var_b

dataclass 可以為簡單的情況自動產生方法,例如,一個__init__接受這些參數並將其分配給自己,之前的小例子可以重寫為:

@dataclass
class MyClass:
 var_a: str
 var_b: str

那麼透過一個例子來看看如何使用吧星際大戰API

#可以使用requests 從星際大戰API 取得資源:

response = requests.get('https://swapi.co/api/films/1/')
dictionary = response.json()

讓我們來看看dictionary (簡化過)的結果:

{
 'characters': ['https://swapi.co/api/people/1/',… ],
 'created': '2014-12-10T14:23:31.880000Z',
 'director': 'George Lucas',
 'edited': '2015-04-11T09:46:52.774897Z',
 'episode_id': 4,
 'opening_crawl': 'It is a period of civil war.\r\n … ',
 'planets': ['https://swapi.co/api/planets/2/', … ],
 'producer': 'Gary Kurtz, Rick McCallum',
 'release_date': '1977-05-25',
 'species': ['https://swapi.co/api/species/5/',…],
 'starships': ['https://swapi.co/api/starships/2/',…],
 'title': 'A New Hope',
 'url': 'https://swapi.co/api/films/1/',
 'vehicles': ['https://swapi.co/api/vehicles/4/',…]

封裝API

#為了正確地封裝一個API,我們應該建立一個使用者可以在其應用程式中使用的對象,因此,在Python 3.6 中定義一個物件來包含requests對/films/endpoint的回應:

##

class StarWarsMovie:
 def __init__(self,
   title: str,
   episode_id: int,
   opening_crawl: str,
   director: str,
   producer: str,
   release_date: datetime,
   characters: List[str],
   planets: List[str],
   starships: List[str],
   vehicles: List[str],
   species: List[str],
   created: datetime,
   edited: datetime,
   url: str
   ):

 self.title = title
 self.episode_id = episode_id
 self.opening_crawl= opening_crawl
 self.director = director
 self.producer = producer
 self.release_date = release_date
 self.characters = characters
 self.planets = planets
 self.starships = starships
 self.vehicles = vehicles
 self.species = species
 self.created = created
 self.edited = edited
 self.url = url

 if type(self.release_date) is str:
  self.release_date = dateutil.parser.parse(self.release_date)

 if type(self.created) is str:
  self.created = dateutil.parser.parse(self.created)

 if type(self.edited) is str:
  self.edited = dateutil.parser.parse(self.edited)

#仔細的讀者可能已經注意到這裡有一些重複的程式碼。

這是使用 dataclass 裝飾器的經典案例,我們需要建立一個主要用來保存資料的類,只需一點驗證,所以讓我們來看看我們需要修改什麼。 首先,data class 自動產生一些dunder 方法,如果我們沒有為data class 裝飾器指定任何選項,則產生的方法有:__init__,__eq__和__repr__,如果你已經定義了__repr__但沒定義__str__,預設情況下Python(不只是data class)將實作傳回__repr__的輸出__str__方法。因此,只需將程式碼變更為以下程式碼即可實作四種dunder 方法:

@dataclass
class StarWarsMovie:
 title: str
 episode_id: int
 opening_crawl: str
 director: str
 producer: str
 release_date: datetime
 characters: List[str]
 planets: List[str]
 starships: List[str]
 vehicles: List[str]
 species: List[str]
 created: datetime
 edited: datetime
 url: str

我們去掉了__init__方法,以確保data class 裝飾器可以加入它所產生的對應方法。不過,我們在這個過程中失去了一些功能,我們的 Python 3.6 建構函數不僅定義了所有的值,還試著解析日期,我們怎麼能用 data class 來做到這一點呢?

如果要覆寫__init__,我們將失去data class 的優勢,因此,如果要處理任何附加功能可以使用新的dunder 方法:__post_init__,讓我們看看__post_init__方法對於我們的包裝類來說是什麼樣子的:
  • def __post_init__(self):
     if type(self.release_date) is str:
      self.release_date = dateutil.parser.parse(self.release_date)
    
     if type(self.created) is str:
      self.created = dateutil.parser.parse(self.created)
    
     if type(self.edited) is str:
      self.edited = dateutil.parser.parse(self.edited)

  • 就是這樣!我們可以使用 data class 裝飾器在用三分之二的程式碼量實作我們的類別。

  • 更多好東西

  • 透過使用裝飾器的選項,可以為用例進一步自訂data class,預設選項是:

  • @dataclass(init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False)

init決定是否要產生__init__ dunder 方法


repr決定是否產生__repr__ dunder方法

eq對__eq__ dunder 方法也是如此,它決定相等性檢查的行為(your_class_instance == another_instance)

##########order 實際上創建了四種dunder 方法,它們確定所有檢查小於,and/or,大於的行為,如果將其設為true,則可以對物件清單進行排序。 ############最後兩個選項決定物件是否可以被哈希化,如果你想使用你的 class 的物件作為字典鍵的話,這是必要的。 ######更多資訊請參考:PEP 557 -- Data Classes##############################

以上是Python 3.7新功能數據class裝飾器詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn