所以我發現自己需要爲Python字典添加前綴。向Python字典鍵添加前綴的最有效方法
基本上我希望這本詞典的用戶能夠在詞典的實例化中添加一個前綴,在這種情況下,詞典包含前綴,並且每次添加一個新的鍵時,都會前綴前綴。但是,如果由於某種原因未提供或更改前綴,我還想要對詞典進行變異,這意味着舊字典鍵需要在保留各自的值的同時將前綴添加到前綴中。
使用案例:
基本上我整理了MWS API最後的API。 我建周圍的想法API,每一個需要調用採取具體參數, ,如:
def get_report(self, marketplaceids):
# Here I process marketplaceids which is a python list
# and send the following to Amazon:
MarketplaceIdList.Id.1: 123,
MarketplaceIdList.Id.2: 345,
MarketplaceIdList.Id.3: 4343
# By doing this I eliminate the complexity of the arguments Amazon expects
遺憾的是,最後兩個API是困難,因爲他們利用一個新的「功能」亞馬遜推出來實現這種方式稱爲Datatypes
。
這些「Datatypes
」是嵌套結構。 例如:
我想打電話從InboundShipmentAPI
的CreateInboundShipment
行動,
的操作採用下列參數:
ShipmentId - String
InboundShipmentHeader - InboundShipmentHeader datatype
InboundShipmentItems - A list of InboundShipmentItem datatypes
問題是因爲InboundShipmentHeader是需要其它數據類型的數據類型論據。 到底亞馬遜預計如下:
ShipmentId=102038383
InboundShipmentHeader.ShipmentName': 'somevalue',
InboundShipmentHeader.ShipFromAddress.Name': 'somevalue',
InboundShipmentHeader.ShipFromAddress.AddressLine1': 'somevalue',
InboundShipmentHeader.ShipFromAddress.City': 'somevalue',
InboundShipmentHeader.ShipFromAddress.StateOrProvinceCode': 'somevalue',
InboundShipmentHeader.ShipFromAddress.PostalCode': 'somevalue',
InboundShipmentHeader.ShipFromAddress.CountryCode': 'somevalue',
InboundShipmentHeader.DestinationFulfillmentCenterId': 'somevalue',
InboundShipmentHeader.ShipmentStatus': 'somevalue',
InboundShipmentHeader.LabelPrepPreference': 'somevalue',
InboundShipmentItems.member.1.QuantityShipped': 'somevalue',
InboundShipmentItems.member.2.QuantityShipped': 'somevalue',
InboundShipmentItems.member.1.SellerSKU': 'somevalue',
InboundShipmentItems.member.2.SellerSKU': 'somevalue',
InboundShipmentHeader.ShipFromAddress.AddressLine2': 'somevalue',
InboundShipmentHeader.ShipFromAddress.DistrictOrCounty': 'somevalue',
,所以我希望把它簡單的人,使這個呼叫而不需要擔心每個參數的名稱。 我的解決方案是創建一個基本數據類型類,然後創建單獨的數據類型 作爲類。
這是我到目前爲止有:
class AmazonDataType(dict):
"""
Base for all Amazon datatypes.
"""
def __init__(self, *args, **kwargs):
self._prefix = kwargs.pop('prefix', '')
self.update(*args, **kwargs)
@property
def prefix(self):
return self._prefix
@prefix.setter
def prefix(self, value):
self._prefix = value
newdict = {'%s.%s' % (value, key): dictvalue for key, dictvalue in self.iteritems()}
self.clear()
dict.update(self, newdict)
def __setitem__(self, key, value):
try:
original_key = self.fields[key]
except KeyError, e:
raise e
if isinstance(value, AmazonDataType):
value.prefix = original_key
dict.update(self, value)
else:
newkey = self.prefix + original_key if self.prefix else original_key
dict.__setitem__(self, newkey, value)
def update(self, *args, **kwargs):
"""
Props to Matt Anderson (http://stackoverflow.com/a/2390997/389453)
"""
for k, v in dict(*args, **kwargs).iteritems():
self[k] = v
class InboundShipmentHeader(AmazonDataType):
fields = {
'name': 'ShipmentName',
'address': 'ShipFromAddress',
'fulfillment_center_id': 'DestinationFulfillmentCenterId',
'label_preference': 'LabelPrepPreference',
'cases_required': 'AreCasesRequired',
'shipment_status': 'ShipmentStatus',
}
然後,而不是做
somedict = {
'InboundShipmentHeader.ShipmentName': 'somevalue',
'InboundShipmentHeader.ShipFromAddress.Name': 'somevalue',
'InboundShipmentHeader.ShipFromAddress.AddressLine1': 'somevalue',
'InboundShipmentHeader.ShipFromAddress.City': 'somevalue',
'InboundShipmentHeader.ShipFromAddress.StateOrProvinceCode': 'somevalue',
'InboundShipmentHeader.ShipFromAddress.PostalCode': 'somevalue',
'InboundShipmentHeader.ShipFromAddress.CountryCode': 'somevalue',
'InboundShipmentHeader.DestinationFulfillmentCenterId': 'somevalue',
'InboundShipmentHeader.ShipmentStatus': 'somevalue',
'InboundShipmentHeader.LabelPrepPreference': 'somevalue',
}
call_amazon(somedict)
的我想通過類似
ShipmentHeader = InboundShipmentHeader()
ShipmentHeader['name'] = 'somevalue'
ShipmentHeader['address'] = address_datatype_instance
ShipmentHeader['fulfillment_center_id'] = 'somevalue'
ShipmentHeader['label_preference'] = 'somevalue'
ShipmentHeader['cases_required'] = 'somevalue'
ShipmentHeader['shipment_status'] = 'somevalue'
call_amazon(ShipmentHeader, otherparams)
在此背景下,call_amazon
方法確實:
ShipmentHeader.prefix = InboundShipmentHeader
您是否還需要在添加新前綴之前刪除舊的前綴? – interjay
在前綴的設置器中,我正在清除字典並用新值替換_prefix的值。 – Paulo
但是,然後你的字典鍵會有新的前綴和前綴。 – interjay