Python 如何将多个参数传递给具有_new__的类?

Python 如何将多个参数传递给具有_new__的类?,python,python-3.x,csv,oop,Python,Python 3.x,Csv,Oop,我正在尝试理解新的东西,而且我对OOP python还相当陌生。我有这个密码 导入csv 从csv导入DictReader 导入日志记录 输入类型为T 类别最大长度(str): 定义新(cls,字段:str): #如何在PCW obj中动态传递此信息 最大值=4 如果len(字段)>最大值: raise VALUETERROR(“+”字段处的字段长度无效) 返回super() 类PCW(T.NamedTuple): 长度检查器:MaxLength @类方法 来自_行的def(cls,行:dict

我正在尝试理解新的东西,而且我对OOP python还相当陌生。我有这个密码

导入csv
从csv导入DictReader
导入日志记录
输入类型为T
类别最大长度(str):
定义新(cls,字段:str):
#如何在PCW obj中动态传递此信息
最大值=4
如果len(字段)>最大值:
raise VALUETERROR(“+”字段处的字段长度无效)
返回super()
类PCW(T.NamedTuple):
长度检查器:MaxLength
@类方法
来自_行的def(cls,行:dict):
返回cls(**{key:type_u(row[key]),对于键,在cls中键入_u。_field_types.items())
def validate_csv(读卡器:DictReader)->bool:
对于读取器中的行:
尝试:
来自世界其他地区(世界其他地区)的PCW
例外情况除外,如e:
logging.error('type:{}msg:{}'。格式(type(e),e))
返回错误
返回真值
输入文件=验证csv(csv.DictReader(打开(“test.csv”))
这是可行的,但我希望能够将
maximum
作为一个参数传入,这样它就会改变。即:

类PCW(T.NamedTuple):
长度检测器:最大长度(最大值=4)
...
输入文件=验证csv(csv.DictReader(打开(“test.csv”))

我想我已经掉进兔子洞了。这是可能的还是我忽略了/误解了什么?

您可以将其作为默认参数:

类最大长度(str):
定义新(cls,字段:str,最大值:int=4):
如果len(字段)>最大值:
raise VALUETERROR(“+”字段处的字段长度无效)
返回super()

您可以将其设置为默认参数:

类最大长度(str):
定义新(cls,字段:str,最大值:int=4):
如果len(字段)>最大值:
raise VALUETERROR(“+”字段处的字段长度无效)
返回super()

一种方法是使用Python 3.6中添加的classmethod。利用它需要对
MaxLength
子类进行子类化

我的意思是:

import csv
from csv import DictReader
import logging
import typing as T


class MaxLength(str):
    maximum = 8

    @classmethod
    def __init_subclass__(cls, **kwargs):
        maximum = kwargs.pop('maximum', cls.maximum)
        super().__init_subclass__(**kwargs)
        cls.maximum = maximum

    def __new__(cls, field: str):
        if len(field) > cls.maximum:
            raise ValueError('invalid length of fields at: ' + field)
        return super().__new__(cls, field)


class PCW(T.NamedTuple):
#    class PCWMaxLength(MaxLength):
    class PCWMaxLength(MaxLength, maximum=4): # Override default maximum.
        pass

    length_checker: PCWMaxLength

    @classmethod
    def from_row(cls, row: dict):
        return cls(**{key: type_(row[key]) for key, type_ in cls._field_types.items()})

    # Display value assigned to nested class' constant.
    print(f'PCWMaxLength.maximum: {PCWMaxLength.maximum}') # -> PCWMaxLength.maximum: 4


def validate_csv(reader: DictReader) -> bool:
    for row in reader:
        try:
            PCW.from_row(row)
        except Exception as e:
            logging.error('type: {} msg: {}'.format(type(e), e))
            return False
    return True

否则,我认为您需要进行一些实际的元类编程…

一种方法是使用Python 3.6中添加的classmethod。利用它需要对
MaxLength
子类进行子类化

我的意思是:

import csv
from csv import DictReader
import logging
import typing as T


class MaxLength(str):
    maximum = 8

    @classmethod
    def __init_subclass__(cls, **kwargs):
        maximum = kwargs.pop('maximum', cls.maximum)
        super().__init_subclass__(**kwargs)
        cls.maximum = maximum

    def __new__(cls, field: str):
        if len(field) > cls.maximum:
            raise ValueError('invalid length of fields at: ' + field)
        return super().__new__(cls, field)


class PCW(T.NamedTuple):
#    class PCWMaxLength(MaxLength):
    class PCWMaxLength(MaxLength, maximum=4): # Override default maximum.
        pass

    length_checker: PCWMaxLength

    @classmethod
    def from_row(cls, row: dict):
        return cls(**{key: type_(row[key]) for key, type_ in cls._field_types.items()})

    # Display value assigned to nested class' constant.
    print(f'PCWMaxLength.maximum: {PCWMaxLength.maximum}') # -> PCWMaxLength.maximum: 4


def validate_csv(reader: DictReader) -> bool:
    for row in reader:
        try:
            PCW.from_row(row)
        except Exception as e:
            logging.error('type: {} msg: {}'.format(type(e), e))
            return False
    return True


否则,,我想你需要用
*args
**kwargs
进行一些实际的元类编程…

。你能给我发一些代码吗?你在哪里实际使用
长度检查器
?长度检查器是CSV文件中的一个字段-对不起,在原始的QQ中,CSV文件中的字段和类是什么属性相关?与
*args
**kwargs
相关。您可以发布一些代码给我看吗?您实际在哪里使用
长度检查器
?长度检查器是CSV文件中的一个字段-很抱歉,在原始QQ中,CSV文件中的字段和类属性如何相关?我如何动态设置int但是在其他地方?@alex你可以像以前一样调用它,可以选择添加第三个参数。例如:
MaxLength(“asdf”)
将有
MaxLength=4
,而
MaxLength(“asdf”,5)
将有
MaxLength=5
Hmm,我得到错误:root:type:msg:'ForwardRef'对象在没有CSV或完全回溯的情况下不可调用,我不知道该错误是如何产生的:/但我如何在其他地方动态设置int?@alex您可以用与以前相同的方式调用它,可以选择添加第三个参数。例如:
MaxLength(“asdf”)
将有
MaxLength=4
MaxLength(“asdf”,5)
将有
MaxLength=5
Hmm,我得到错误:root:type:msg:'ForwardRef'对象在没有CSV或完全回溯的情况下是不可调用的,我不知道如何产生这个错误:/谢谢martin让我摆脱痛苦,这是有效的,而且我学到了一些新的东西:D谢谢你,马丁让我摆脱了痛苦,这是有效的,而且我学到了一些新的东西:D