python typedtuple是一个带有类型强制的namedtuple,它还包含StrictTuple的原始代码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python typedtuple是一个带有类型强制的namedtuple,它还包含StrictTuple的原始代码相关的知识,希望对你有一定的参考价值。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author: codykochmann
# @Date:     2017-04-06 13:35:45
# @Last Modified time: 2017-05-21

from collections import namedtuple
import inspect
import sys

class typedtuple(object):
    """ typedtuple is a namedtuple with type enforcement """

    _example_usage="""\n\nExample Usage:\n
    Point = typedtuple(
        'Point',
        x = int,
        y = int
    )\n"""
    _one_arg_needed="typedtuple needs one argument that will serve as the structname.{}".format(_example_usage)

    def __init__(self, *args, **kwargs):
        assert len(args) == 1, self._one_arg_needed
        self.validate_all_types(kwargs)
        self.fields=kwargs
        self.name=args[0]
        self.namedtuple=namedtuple(
            self.name,
            self.fields.keys()
        )

    @staticmethod
    def suggest_correct_type_defining(key, value):
        return

    @staticmethod
    def validate_all_types(kwargs):
        """ validates that all values of the arguments are types """
        for key in kwargs:
            assert isinstance(kwargs[key], type), """\n
    Typedtuple needs its arguments to be types. Argument "{k:}" was {type_name:}({val_repr}).
    You might want to try:
        {k:} = {type_name:}\n\n""".format(k=key, type_name=type(kwargs[key]).__name__, val_repr=kwargs[key].__repr__())

    def validate_fields(self, **kwargs):
        """ ensures that all incoming fields are the types that were specified """
        for field in self.fields:
            value = kwargs[field]
            required_type = self.fields[field]
            if type(value) != required_type:
                raise TypeError('{}.{} needs to be a {}, recieved: {}({})'.format(
                    self.name,
                    field,
                    required_type.__name__,
                    type(value).__name__,
                    value.__repr__()))

    def __call__(self, **kwargs):
        """ validates that the values match the specifications and
            returns a namedtuple with those fields and values """
        self.validate_fields(**kwargs)
        return self.namedtuple(**kwargs)

class stricttuple():
    @staticmethod
    def extract_types(*args):
        return (i for i in args if type(i) == type)

    @staticmethod
    def is_type(obj, *typ):
        assert len(typ) >= 1
        types = (i for i in typ if type(i) == type)
        return any((type(obj)==t) for t in types)

    def __init__(self, *args, **kwargs):
        args = args
        kwargs = kwargs
        self.namedtuple=namedtuple(
            args[0],
            kwargs.keys()
        )
        self.name=args[0]
        # validate the arguments coming in
        allowed_types = tuple, type
        assert len(args) == 1
        assert type(args[0]) == str
        assert all(type(v) in allowed_types for v in kwargs.values())
        
        lambda_type = type(lambda:1)
        allowed_types_in_tuples = type, lambda_type
        self.__saved_rules__={}
        for k in kwargs:
            v = kwargs[k]
            if type(v) == tuple:
                self.__saved_rules__[k]=[]
                for i in v:
                    assert type(i) in allowed_types_in_tuples
                    if type(i) == type:
                        self.__saved_rules__[k].append(lambda _:type(_)==i)
                    else:
                        self.__saved_rules__[k].append(i)
        #print(self.__saved_rules__)

    def __call__(self, **kwargs):
        """ validates that the values match the specifications and
            returns a namedtuple with those fields and values """
        for k in kwargs:
            v = kwargs[k]
            for r in self.__saved_rules__[k]:
                if not r(v):
                    exit('stricttuple rule violation\ninstruction:\n\t{}.{} = {}({})\nviolates the rule:\n\t{}'.format(
                        self.name,
                        k,
                        type(v).__name__,
                        repr(v),
                        inspect.getsource(r).strip()
                        ))
        return self.namedtuple(**kwargs)

if __name__ == '__main__':

    Point = typedtuple(
        'Point',
        x = int,
        y = int
    )

    t = Point(
        x = 3,
        y = 42
    )

    print(t)

    Point = stricttuple(
        "Point",
        x = (
             lambda x:type(x)==int,
             lambda x:x<15 and x>=0
        ),
        y = (
             lambda y:type(y)==int,
             lambda y:y<15 and y>=0
        )
    )
    from random import randint
    for i in range(32):
        t = Point(
            x=randint(0, 15),
            y=randint(0, 16)
        )
        print(t)

以上是关于python typedtuple是一个带有类型强制的namedtuple,它还包含StrictTuple的原始代码的主要内容,如果未能解决你的问题,请参考以下文章

Python的语言类型

python 是强类型语言吗?

Python动态强类型解释型语言

弱类型语言与强类型语言

为啥说 Python 是强类型语言

python到底是强类型语言,还是弱类型语言?