python学习笔记6.7-简化数据结构的初始化过程
2016-12-20 20:47
344 查看
我们每编写一个类的时候都需要编写一个初始化函数,那么如果编写的类当做数据结构来用,它们的初始化结构就是一样的,例如:
每一个类写一个数据结构这样比较麻烦,可以利用其它有效的方法去避免这种麻烦,加快编写代码的速度,例如,将初始化数据结构的步骤归纳到一个单独的init()函数中,并将其定义在公共的基类中:
这样我们还可以继续创建各种基于Structure的类,方便快捷。究其本质而言,这种方法很好的利用了类的继承。
可以对上面的方法进行完善,对其添加对关键字参数的支持,这样表达更清晰,更方便编程,最好的选择就是对关键字参数做映射,这样它们就只能对应于定义在-fields中的属性名:
还可以利用关键字参数来给类添加额外的属性,而这些额外的属性是没有定义在_fields中的:
从示例中可
4000
以发现:我们都是使用setattr()函数来将传递进来的属性参数添加到对应的属性上。与此不同的是,还可以选择直接访问示例字典的办法来添加属性。
这么写看似高端简单,但是对于python程序来说是不严谨的。如果某个子类使用slot()方法或者@property(或者描述符)包装了某个特定的属性,直接访实例的字典就会产生崩溃。因而不建议使用这种写法。
尽管简化数据结构的几种方法都十分的实用,但是它的缺点就是会影响到IDE的文档和帮助,如果用户针对于某个特定的类寻求帮助,那么所需的参数就不会以正常的形式来表达。
虽然可以通过在init()中强制签名来解决这个bug,但是不仅会增加程序员的工作量,而且运行速度也比较慢,所以不推荐。
class Stock: def __init__(self,name,shares,price): self.name = name self.shares = shares self.price = price class Point: def __init__(self,x,y): self.x = x self.y = y class Circle: def __init__(self,radius): self.radius = radius
每一个类写一个数据结构这样比较麻烦,可以利用其它有效的方法去避免这种麻烦,加快编写代码的速度,例如,将初始化数据结构的步骤归纳到一个单独的init()函数中,并将其定义在公共的基类中:
class Structure: _fields=[] def __init__(self,*args): if len(args) != len(self._fields): raise TypeError('Expected {} arguements'.format(len(self._fields))) #set the arguments for name, value in zip(self._fields,args): setattr(self,name,value) class Stock(Structure): _fields = ['name','shares','prices'] s = Stock('ACER',50,99) print(s.name,s.shares,s.prices) class Point(Structure): _fields = ['x','y'] p = Point(4,5) print(p.x,p.y) 打印输出: ACER 50 99 4 5
这样我们还可以继续创建各种基于Structure的类,方便快捷。究其本质而言,这种方法很好的利用了类的继承。
可以对上面的方法进行完善,对其添加对关键字参数的支持,这样表达更清晰,更方便编程,最好的选择就是对关键字参数做映射,这样它们就只能对应于定义在-fields中的属性名:
class Structure: _fields=[] def __init__(self,*args,**kwargs): if len(args) > len(self._fields): raise TypeError('Expected {} arguments'.format(len(self._fields))) #set the arguments for name, value in zip(self._fields,args): setattr(self,name,value) for name in self._fields[len(args):]: setattr(self,name,kwargs.pop(name)) if kwargs: raise TypeError('Invided arguments : {}'.format(','.join(kwargs))) class Stock(Structure): _fields = ['name','shares','prices'] s = Stock('ACER',50,prices=99) print(s.name,s.shares,s.prices) class Point(Structure): _fields = ['x','y'] p = Point(x=4,y=5) print(p.x,p.y) 打印输出: ACER 50 99 4 5
还可以利用关键字参数来给类添加额外的属性,而这些额外的属性是没有定义在_fields中的:
class Structure: _fields=[] def __init__(self,*args,**kwargs): if len(args) > len(self._fields): raise TypeError('Expected {} arguments'.format(len(self._fields))) #set the arguments for name, value in zip(self._fields,args): setattr(self,name,value) for name in self._fields[len(args):]: setattr(self, name, kwargs.pop(name)) extra_args = kwargs.keys() - self._fields for name in extra_args: setattr(self,name,kwargs.pop(name)) if kwargs: raise TypeError('Invided arguments : {}'.format(','.join(kwargs))) class Stock(Structure): _fields = ['name','shares','prices'] s = Stock('ACER',50,prices = 99,date = '2012-2-2') print(s.name,s.shares,s.prices,s.date) class Point(Structure): _fields = ['x','y'] p = Point(4,5) print(p.x,p.y)
从示例中可
4000
以发现:我们都是使用setattr()函数来将传递进来的属性参数添加到对应的属性上。与此不同的是,还可以选择直接访问示例字典的办法来添加属性。
class Structure: _fields=[] def __init__(self,*args,**kwargs): if len(args) > len(self._fields): raise TypeError('Expected {} arguments'.format(len(self._fields))) #set the arguments self.__dict__.update(zip(self._fields,args)) class Stock(Structure): _fields = ['name','shares','prices'] s = Stock('ACER',50,99) print(s.name,s.shares,s.prices) class Point(Structure): _fields = ['x','y'] p = Point(4,5) print(p.x,p.y)
这么写看似高端简单,但是对于python程序来说是不严谨的。如果某个子类使用slot()方法或者@property(或者描述符)包装了某个特定的属性,直接访实例的字典就会产生崩溃。因而不建议使用这种写法。
尽管简化数据结构的几种方法都十分的实用,但是它的缺点就是会影响到IDE的文档和帮助,如果用户针对于某个特定的类寻求帮助,那么所需的参数就不会以正常的形式来表达。
print(help(Stock)) 打印输出: class Stock(Structure) | Method resolution order: | Stock | Structure | builtins.object | | Data and other attributes defined here: | | _fields = ['name', 'shares', 'prices'] | | ---------------------------------------------------------------------- | Methods inherited from Structure: | | __init__(self, *args, **kwargs) | Initialize self. See help(type(self)) for accurate signature. | | ---------------------------------------------------------------------- | Data descriptors inherited from Structure: | | __dict__ | dictionary for instance variables (if defined) | | __weakref__ | list of weak references to the object (if defined) None
虽然可以通过在init()中强制签名来解决这个bug,但是不仅会增加程序员的工作量,而且运行速度也比较慢,所以不推荐。
相关文章推荐
- coco2dx-2.2.2 win32启动过程(opengl 和 窗口大小初始化部分) - 学习笔记 1
- Python学习笔记——基本数据结构
- python数据结构学习笔记-3-数组
- python 学习笔记3(循环方式;list初始化;循环对象/生成器/表推导;函数对象;异常处理)
- Java学习笔记(注释、对象初始化过程、单例模式)
- python学习笔记2:数据结构
- Python学习笔记四:过程控制
- Java学习笔记(十三):关于子类初始化的过程
- Python 2.7.11 基本语法和数据结构学习笔记
- Android(java)学习笔记159:Dalivk虚拟机的初始化过程
- 深入浅出MFC学习笔记:MFC六大关键技术仿真之MFC程序的初始化过程
- Python学习笔记(二)Pytho解释器和程序开发、执行过程
- java学习笔记_类建立对象初始化过程分析
- python数据结构学习笔记-4-堆栈 队列
- Python学习笔记(7):数据结构
- 深入浅出MFC学习笔记:MFC六大关键技术仿真之MFC程序的初始化过程
- python学习笔记,以此开始记录自己的python学习过程
- 学习python笔记——数据结构
- Python中列表、字典、元组数据结构的简单学习笔记
- python数据结构学习笔记-4-链表