我阅读了文档,但不确定如何使用Python属性简化以下代码:
envelopesApi.GetDocument(accountId, envelopeID, "combined")
答案 0 :(得分:3)
您可以覆盖使用obj.prop
访问媒体资源时调用的__getattr__
和__setattr__
。
class PatientRecordJson:
properties = ['raw_data', 'data_type', 'type_of_record', 'npi']
def __init__(self):
self.json = {}
def __getattr__(self, name):
if name in PatientRecordJson.properties:
return self.json.get(name)
return super().__getattr__(name)
def __setattr__(self, name, value):
if name in PatientRecordJson.properties:
self.json[name] = value
return super().__setattr__(name, value)
用法示例:
pr = PatientRecordJson()
pr.raw_data #=> None
pr.raw_data = 'raw data'
pr.raw_data #=> 'raw data'
pr.json #=> {'raw_data': 'raw data'}
pr.z #=> AttributeError
pr.z = 2
pr.z #=> 2
pr.json #=> {'raw_data': 'raw data'}
注意:您已在课程中定义了json
,如果您希望它是实例变量,请在self
的{{1}}上创建它。
答案 1 :(得分:1)
如果您只是学习Python,这可能过于先进 - 但是通过使用它,您可以通过使用元类(其实例为其他类的类)在很大程度上自动化创建任意数量的类的过程。 / p>
虽然这样做需要一些非平凡的代码,但它使得定义目标类非常简单。另外,作为奖励,我添加了可选的类型检查。
def typed_property(field_name, expected_type=None):
""" Helper function which creates and returns a property with the given
name with optional type-checking. Each property retrieves or stores
values from/to an instance-defined "json" dictionary attribute.
"""
@property
def prop(self):
return self.json[field_name]
@prop.setter
def prop(self, value):
if expected_type and not isinstance(value, expected_type):
raise TypeError('Only {} values may be assigned to {}'.format(
expected_type.__name__, field_name))
self.json[field_name] = value
return prop
class PatientRecordMeta(type):
""" Metaclass to define properties based on a class-level defined "fields"
dictionary.
"""
def __new__(metaclass, classname, bases, classdict):
cls = super().__new__(metaclass, classname, bases, classdict)
fields = classdict.get('fields')
if not fields or not isinstance(fields, dict):
raise TypeError('Class {} did not define required "fields" '
'instance dictionary'.format(classname))
# Create the properties.
for field, expected_type in fields.items():
setattr(cls, field, typed_property(field, expected_type))
return cls
定义的元类使得创建具有所需属性的类非常容易:
class PatientRecordJson(metaclass=PatientRecordMeta):
fields = {'raw_data': str,
'data_type': str,
'type_of_record': str,
'npi': int} # Note changed to "int" to test type-checking,
def __init__(self):
self.json = {} # define required instance attribute
# Other methods could be defined here, too, if desired.
# ...
patient_rec = PatientRecordJson()
patient_rec.raw_data = 'something'
patient_rec.bogus = 'something else' # OK, but not saved in "self.json" dict.
try:
patient_rec.npi = 'spam' # -> Should cause a TypeError
except TypeError:
pass # expected TypeError occurred
else:
print('Error: a TypeError did not occur as expected')
patient_rec.npi = 42 # Integer value is OK.
patient_rec.json['raw_data'] = 'eggs' # can still do this
print(patient_rec.raw_data) # -> eggs
print(patient_rec.npi) # -> 42
print(patient_rec.json) # -> {'raw_data': 'something', 'npi': 42}
答案 2 :(得分:0)
您可以使用__getattr__
和__setattr__
将动态字段视为对象本身的属性,而不是内部json
对象的属性。
class PatientRecordJson:
def __init__(self):
self.fields = ['raw_data', 'data_type', 'type_of_record', 'npi']
self.json = {}
def __getattr__(self, key):
if key not in self.fields:
raise AttributeError
return self.json.get(key, None)
def __setattr__(self, key, data):
if key not in self.fields
raise AttributeError
self.json[key] = data
上面的示例将允许您访问类似的属性。
patient = PatientRecordJson()
patient.data_type = 'something'
patient.npi = 12345
patient.raw_data = 'whatever you want here'
print(patient.data_type) # 'something'
print(patient.doesntexist) # AttributeError
patient.notinfields = True # AttributeError