雖然我用3.6,但我在2.7轉3.6時候,把3.3 3.4 3.5 3.6的變化都看了一次,雖然已經忘了哪些變化。同時也關注3.7 3.8的變化,3.7中就有1個數據類印象深入,由於以前在定義這種類時候,我基本上是按照以下截圖作的,self.xx。json
py 3.7數據類介紹app
數據類比字典和具名元祖都強大,規範更好,更容易補全,由於pycharm能自動補全,基本不會出現打錯字母的狀況。函數
爲何不spa
class A():debug
x = Nonecode
y= None對象
這樣作呢,由於這樣寫的x和y都是類屬性,不是實例屬性,類在解釋器是惟一的,類 屬性也是惟一的,基本上要實現多實例互補干擾,必須使用實例化類後的多個對象,這樣每一個對象的實例屬性纔是互不干擾的。blog
若是不想 utf-8
class A():get
def __init__():
self.x = None
self.y = None
每次定義數據類都要加個self,那麼就應該發明一個數據類。
選擇元類實現是一個不錯的選擇。
# -*- coding: utf-8 -*- # @Author : ydf # @Time : 2019/6/12 17:25 import copy import json from app.utils_ydf import simple_logger class DataMetaclass(type): def __call__(self, *args, **kwargs): instance = super().__call__(*args, **kwargs) instance.__dict__ = copy.deepcopy({k: v for k, v in self.__dict__.items() if not k.startswith('__')}) # 類屬性自然自帶其餘幾個__的屬性。 return instance class DataClassBase(metaclass=DataMetaclass): def get_dict(self): return self.__dict__ def get_json(self): return json.dumps(self.__dict__) def __str__(self): return f"{self.__class__} {json.dumps(self.__dict__)}" if __name__ == '__main__': # 實例屬性和類屬性隔離。 class ShopItem(DataClassBase): a = 1 shop_item = ShopItem() shop_item.a = 2 simple_logger.debug(shop_item) shop_item = ShopItem() simple_logger.debug(shop_item) shop_item.a = 3 simple_logger.debug(shop_item) simple_logger.debug(ShopItem.a) # print(shop_item.__dict__)
這樣就達到效果了。既不用寫self,但又作到了類屬性和各對象實例屬性的隔離。
使用元類時候,定義元類裏面的self,self表明的是類,和普通的類建立對象,self指的是改類的對象不同。因此思惟要降維。
元類通常來講是用來控制建立類的行爲,寫__new__ 寫 __init__改變(增長)類的屬性和方法,但要改變該類實例化的對象的建立行爲,那就要使用__call__了,元類的__call__,就改變了普通類的__new__,思惟要降維,元類是建立類的類,普通類是建立對象的類。實例的類型是類名,類的類名是type。
用元類小題大作了嗎。也可使用裝飾器來裝飾類來實現數據類,裝飾器不光能夠裝飾在函數上,也能夠裝飾在類上的。