How do I use a keyword as a variable name?

前端 未结 3 508
面向向阳花
面向向阳花 2020-11-30 12:54

I have the following class with the variables from, to and rate. from is a keyword. If I want to use it in the init metho

相关标签:
3条回答
  • 2020-11-30 13:18

    Add a single underscore to your preferred names: from_ and to_

    (see PEP 8)

    class ExchangeRates(JsonAware):
        def __init__(self, from_, to_, rate):
            self.from = from_
            self.to = to_
            self.rate = rate
    
    0 讨论(0)
  • 2020-11-30 13:19

    Use a synonym. Try "origin" or "source" instead.

    0 讨论(0)
  • 2020-11-30 13:31

    As mentioned in the comments, from is a Python keyword so you can't use it as a variable name, or an attribute name. So you need to use an alternative name, and do a conversion when reading or writing the JSON data.

    To do the output conversion you can supply a new encoder for json.dumps; you can do that by overriding the ExchangeRates.json method. To do the input conversion, override ExchangeRates.from_json.

    The strategy is similar in both cases: we create a copy of the dictionary (so we don't mutate the original), then we create a new key with the desired name and value, then delete the old key.

    Here's a quick demo, tested on Python 2.6 and 3.6:

    import json
    
    class PropertyEquality(object):
        def __eq__(self, other):
            return (isinstance(other, self.__class__) and self.__dict__ == other.__dict__)
    
        def __ne__(self, other):
            return not self.__eq__(other)
    
        def __repr__(self):
            return '%s(%s)' % (self.__class__.__name__, ', '.join(['%s=%s' % (k, v) for (k, v) in self.__dict__.items()]))
    
    class JsonAware(PropertyEquality):
        def json(self):
            return json.dumps(self, cls=GenericEncoder)
    
        @classmethod
        def from_json(cls, json):
            return cls(**json)
    
    class ExchangeRatesEncoder(json.JSONEncoder):
        def default(self, obj):
            d = obj.__dict__.copy()
            d['from'] = d['frm']
            del d['frm']
            return d
    
    class ExchangeRates(JsonAware):
        def __init__(self, frm, to, rate):
            self.frm = frm
            self.to = to
            self.rate = rate
    
        def json(self):
            return json.dumps(self, cls=ExchangeRatesEncoder)
    
        @classmethod
        def from_json(cls, json):
            d = json.copy()
            d['frm'] = d['from']
            del d['from']
            return cls(**d)
    
    # Test
    
    a = ExchangeRates('a', 'b', 1.23)
    print(a.json())
    
    jdict = {"from": "z", "to": "y", "rate": 4.56, }
    
    b = ExchangeRates.from_json(jdict)
    print(b.json())    
    

    typical output

    {"from": "a", "to": "b", "rate": 1.23}
    {"from": "z", "to": "y", "rate": 4.56}
    
    0 讨论(0)
提交回复
热议问题