Python “有什么诀窍吗?”;重载点运算符“;?
我知道这个问题有点奇怪,但我想不出任何其他的说法。我有一个处理大型json对象的应用程序,我想说: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()方
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(通用对象