Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python “有什么诀窍吗?”;重载点运算符“;?_Python_Json - Fatal编程技术网

Python “有什么诀窍吗?”;重载点运算符“;?

Python “有什么诀窍吗?”;重载点运算符“;?,python,json,Python,Json,我知道这个问题有点奇怪,但我想不出任何其他的说法。我有一个处理大型json对象的应用程序,我想说: object1.value.size.whatever.attributexyz 而不是 object1.get('value').get('size').get('whatever').get('attributexyz') 是否有一些聪明的方法来捕获将引发的AttributeError,并在数据结构内部检查该属性是否与其任何值对应 使用defined\uuu getattr\uuuu()方

我知道这个问题有点奇怪,但我想不出任何其他的说法。我有一个处理大型json对象的应用程序,我想说:

object1.value.size.whatever.attributexyz
而不是

object1.get('value').get('size').get('whatever').get('attributexyz')

是否有一些聪明的方法来捕获将引发的
AttributeError
,并在数据结构内部检查该属性是否与其任何值对应

使用defined
\uuu getattr\uuuu()方法将结构包装到对象中。如果您对该结构有任何控制权,则可以定义它自己的
\uuu getattr\uuuuu()
。Getattr只做您想做的事情——“捕获”缺少的属性并可能返回一些值。

object1
的类定义中

def __getattr__(self, key):
    return self.get(key)
解析对象本身不存在的属性、方法或字段名的任何尝试都将传递给

如果您没有访问类定义的权限,例如,它类似于字典,请将其包装到类中。对于字典,您可以执行以下操作:

class DictWrapper(object):
    def __init__(self, d):
        self.d = d
    def __getattr__(self, key):
        return self.d[key]
请注意,如果密钥无效,将引发KeyError;然而,惯例是提出一个属性错误(谢谢,S.洛特!)。如有必要,您可以像这样将KeyError重新提升为AttributeError:

try:
    return self.get(key)
except KeyError as e:
    raise AttributeError(e)

还请记住,如果您从
\uuu getattr\uuuu>返回的对象也是字典,那么您也需要将它们包装起来。

仅用一个示例来补充上述答案

class A:
    def __init__(self, *args):
        self.args = args

    def dump(self, *args):
        print(self.args, args)
        return self.args, args

class Wrap:
    def __init__(self, c, init_args):
        self.c, self.init_args = c, init_args

    def __getattr__(self, key):
        inst = self.c(*self.init_args)
        return getattr(inst, key)

a = Wrap(A, (1, 2, 3))
a.dump(4, 5, 6)

b = Wrap(dict, ({1:2},))
print(b.get(1), b.get(3))

# This will fail                                                                                                                                                                                                                                  
print(b[1])
产出

$ python --version
Python 3.6.3
$ python wrap.py 
(1, 2, 3) (4, 5, 6)
2 None
Traceback (most recent call last):
  File "wrap.py", line 24, in <module>
    print(b[1])
TypeError: 'Wrap' object does not support indexing
$python--版本
Python 3.6.3
$python wrap.py
(1, 2, 3) (4, 5, 6)
2无
回溯(最近一次呼叫最后一次):
文件“wrap.py”,第24行,在
打印(b[1])
TypeError:“Wrap”对象不支持索引

我想做同样的事情,只是开始玩,然后想出了一个可以做同样事情的类(如下所示)

这可能不是最漂亮的东西,但它确实有用

例子 loads()的结果实际上是一个dict或list,因此您可以使用该调用的返回。例如,在使用属性之前,传入dict并检查属性是否存在:

dumm_dict = {
    "name" : "1289378F67A",
    "location" : "eastus"
}

dummy_generic = GenericObject(dumm_dict)

if GenericObject.has_property(dummy_generic, ["name"]):
    print(dummy_generic.name, dummy_generic.location)
等级
类GenericObject:
'''
类,该类将json对象分解为具有属性的类
命名与json对象相同,因此不必继续使用
字典索引,以了解您的目标。
'''
定义初始化(self,属性:dict):
"""
构造函数获取字典或列表并创建
一个通用对象。
对于纯列表,该属性将被称为“列表”,
否则,属性将使用相应的字典命名
键值。
"""
如果存在(属性、指令):
parsed=generiobject.\u expand\u dict(属性)
对于已解析的.keys()中的项:
self.\uuuu setattr\uuuuu(项,已解析的[项])
elif isinstance(属性、列表):
已解析=GenericObject.\u展开\u列表(属性)
self.\uuuu setattr\uuuuu(“列表”,已解析)
其他:
打印(“未知”,属性)
引发异常(“未知类型…”)
@静力学方法
def具有属性(通用对象、属性列表):
"""
确定给定GenericObject上是否存在属性
泛型对象:泛型对象的实例
属性列表:属性字符串的列表。如果有多个属性,它将
在假定子属性的对象中行进。
"""
prop_available=False
如果isinstance(通用对象、通用对象):
阶梯式对象=通用对象
对于道具列表中的道具:
如果isinstance(stepped_对象,GenericObject)和hasattr(stepped_对象,prop):
prop_available=True
stepped_对象=getattr(stepped_对象,道具)
其他:
prop_available=False
打破
返回道具可用
@静力学方法
def find_属性(通用_对象、属性名称):
"""
返回包含给定属性名称的通用对象列表
泛型对象:泛型对象的实例
prop_name:要查找的属性名称
"""
返回\u泛型\u对象=[]
如果isinstance(通用对象、通用对象):
gen_variables=vars(通用_对象)
对于gen_variables.keys()中的变量:
如果变量==项目名称:
#它有一个。。。
返回\u泛型\u对象。追加(泛型\u对象)
如果isinstance(gen_变量[variable],GenericObject):
#属性是一个gen对象
sub_obs=generiobject.find_属性(gen_变量[variable],prop_名称)
返回\u通用\u对象。扩展(子\u obs)
如果存在(gen_变量[变量],列表):
对于gen_变量[变量]中的子_列表_项:
#属性是一个gen对象
sub_obs=GenericObject.find_属性(sub_列表_项,属性名称)
返回\u通用\u对象。扩展(子\u obs)
返回\u通用\u对象
@静力学方法
def dumpObject(通用对象,缩进=0,可选结尾=“”):
"""
dumpObject打印出GenericObject实例的内容
这样用户就可以看到它是正确构建的。
泛型对象=泛型对象实例
缩进=缩进打印行的空格数
可选\u结束=可选的行结束
缩进和可选的_-end都在内部使用,如果您想添加一个,
去做吧,但这不是必须的。
"""
缩进字符串=“”
如果缩进>0:
缩进字符串=“缩进”
if isinstance(通用对象