Python 使用继承从_uinit__;减少样板文件

Python 使用继承从_uinit__;减少样板文件,python,python-internals,Python,Python Internals,我试图通过超类注入构造函数,即\uuuu init\uuu,以避免在我所有的域类中使用\uuuu init\uuu中的样板代码 例如: class Structure: _fields = [] def __init__(self, *args): if len(args) != len(self._fields): raise TypeError("Wrong # arguments") for name, value

我试图通过超类注入构造函数,即
\uuuu init\uuu
,以避免在我所有的域类中使用
\uuuu init\uuu
中的样板代码

例如:

class Structure:
    _fields = []

    def __init__(self, *args):
        if len(args) != len(self._fields):
            raise TypeError("Wrong # arguments")
        for name, value in zip(self._fields, args):
            setattr(self, name, value)

class Stock(Structure):
    _fields = ['name', 'shares', 'price']

stock = Stock("Amzn", "11", "2100")
print(stock.name)
当构造函数限制为
*args
时,上面的代码可以正常工作。但是也有一些域类需要
**kwargs

例如,如下所示:

class Structure:
    _fields = []

    def __init__(self, *args, **kwargs):
        if (len(args) + len(kwargs)) != len(self._fields):
            raise TypeError("Wrong # arguments")

        for name, value in zip(self._fields, args):
            setattr(self, name, value)

class Stock(Structure):
    _fields = ['name', 'shares', 'price']

stock = Stock("Amzn", "11", price = "2100")
stock.price #AttributeError, stock object has no attribute 'price'

但是显然上面的代码不会设置kwargs,因为我在
\uuuu init\uuuu
中从未接触过kwargs。知道如何修复此问题吗?

检查是否存在
kwargs

>>> class SC: 
...:     _fields = [] 
...:     def __init__(self, *args, **kwargs):
...:         if (len(args) + len(kwargs)) != len(self._fields):
...:              raise TypeError("Wrong # arguments") 
...:         for name, value in zip(self._fields, args): 
...:             setattr(self, name, value) 
...:         if kwargs: 
...:             self.__dict__.update(kwargs) 
...:                                                                                                                                                                                      

>>> class SD2(SC): 
...     _fields = ['name', 'shares', 'price'] 


>>> i = SD2(name='Amzn', shares=1, price=2)                                                                                                                                              
>>> i.name                                                                                                                                                                               
'Amzn'
>>> i.shares  
1
它也是这样工作的:

>>>u= SD2('Amzn', shares=1, price=2)                                                                                                                                                             
>>>u.name                                                                                                                                                                                
'Amzn'

检查kwargs是否存在如何

>>> class SC: 
...:     _fields = [] 
...:     def __init__(self, *args, **kwargs):
...:         if (len(args) + len(kwargs)) != len(self._fields):
...:              raise TypeError("Wrong # arguments") 
...:         for name, value in zip(self._fields, args): 
...:             setattr(self, name, value) 
...:         if kwargs: 
...:             self.__dict__.update(kwargs) 
...:                                                                                                                                                                                      

>>> class SD2(SC): 
...     _fields = ['name', 'shares', 'price'] 


>>> i = SD2(name='Amzn', shares=1, price=2)                                                                                                                                              
>>> i.name                                                                                                                                                                               
'Amzn'
>>> i.shares  
1
它也是这样工作的:

>>>u= SD2('Amzn', shares=1, price=2)                                                                                                                                                             
>>>u.name                                                                                                                                                                                
'Amzn'

像单行构造函数这样的东西可能就是你想要的?请看此网页的底部:如果是我负责的任何事情,我很可能会把我的显示器扔给编写代码的人;)当然,它可能会节省一点样板文件,但由于它不是标准惯例,如果您想要依赖Python的工具,您将遇到各种各样的问题。例如,您尝试执行的操作会使help()完全无用。您无法分配类型提示(如果您选择这样做)。等etc@DemianBrecht,而你的评论是有道理的。我见过一些代码使用类似的技巧在运行时定义类和类型。当然,在Python中也有其他方法可以做到这一点,但在所有这些情况下,您不需要帮助和“标准”工具,尤其是在编写框架或库时。你也可以在Django、Flask等网站上发现类似的事情。你想要的可能是单线构造函数?请看此网页的底部:如果是我负责的任何事情,我很可能会把我的显示器扔给编写代码的人;)当然,它可能会节省一点样板文件,但由于它不是标准惯例,如果您想要依赖Python的工具,您将遇到各种各样的问题。例如,您尝试执行的操作会使help()完全无用。您无法分配类型提示(如果您选择这样做)。等etc@DemianBrecht,而你的评论是有道理的。我见过一些代码使用类似的技巧在运行时定义类和类型。当然,在Python中也有其他方法可以做到这一点,但在所有这些情况下,您不需要帮助和“标准”工具,尤其是在编写框架或库时。你也可以在Django等地发现这样的事情。