虽然我用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。
用元类小题大作了吗。也可使用装饰器来装饰类来实现数据类,装饰器不光能够装饰在函数上,也能够装饰在类上的。