3

我有一个类定义,如下所示。

class Ace11():
    def __init__(self, register_list):
        """
        Parse and validate the list of dicts.
        """
        self.required_keys = """
            briefdescription defaultvalue flatname rnum rtype where
            """.strip().split()
        self.registers = register_list
        ## Validate
        for d in self.registers:
            if not isinstance(d, dict):
                raise TypeError("{d} is not a dict.".format(**locals()))

            for k in self.required_keys:
                if not k in d.keys():
                    raise ValueError("Key {k} missing from {d}"
                                     .format(**locals()))

当我尝试在客户端使用包含对象数组的 var 实例化它时,会引发 TypeError,这可能是因为 isinstance 对什么是 dict 什么不是非常直接。我想保持验证不变,因为相同的代码在服务器端很有用。

处理这个问题的正确方法是什么?

4

1 回答 1

4

问题是 JS 对象本质上没有完整的 dicts,它们遗漏了许多方法。但它们可以由dict ()构造函数转换为字典。这是非常快的,因为没有数据被复制,只有原型被改变以包含所需的 dict 方法。

isinstance方法当然可以更改为返回 True on isinstance (<anyJsObject>, dict)。但这将无法区分字典和对象。所以可以调用对象没有的方法。这超出了类型检查的目的。

由于您希望服务器和客户端上的代码保持相同,您可以register_list在调用之前将您的 JS 对象转换为 dict 。

但是检查将不再有意义(至少在客户端上),因为register_list在这种情况下,确实所有元素肯定都是字典。

因此,或者,您可以省略检查,但您说要保留验证。

更精细的替代方法是使用相同的源代码,但对 Transcrypt 进行一种检查,对 CPython 进行另一种检查:

from org.transcrypt.stubs.browser import __envir__

if __envir__.executor_name == __envir__.transpiler_name:
    <do Transcrypt validation and, possibly, conversion, or nothing at all>
else:
    <do CPython validation>

例如,您可以在 Transcrypt 中检查某物是否为 JS 对象,然后通过调用其上的 dict 构造函数将其转换为 dict。

于 2017-04-28T13:58:58.440 回答