简体   繁体   中英

use str.format() witch class in python

I have a class with __getitem__() function which is subscribable like a dictionary. However, when I try to pass it to a str.format() i get a TypeError . How can I use a class in python with the format() function?

>>> class C(object):
      id=int()
      name=str()

      def __init__(self, id, name):
        self.id=id
        self.name=name

      def __getitem__(self, key):
        return getattr(self, key)

>>> d=dict(id=1, name='xyz')
>>> c=C(id=1, name='xyz')
>>>
>>> #Subscription works for both objects
>>> print(d['id'])
1
>>> print(c['id'])
1
>>>
>>> s='{id} {name}'
>>> #format() only works on dict()
>>> print(s.format(**d))
1 xyz
>>> print(s.format(**c))
Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    print(s.format(**c))
TypeError: format() argument after ** must be a mapping, not C

As some of the comments mention you could inherit from dict , the reason it doesn't work is that:

If the syntax **expression appears in the function call, the expression must evaluate to a mapping, the contents of which are treated as additional keyword arguments. In the case of a keyword appearing in both expression and as an explicit keyword argument, a TypeError exception is raised.

For it to work you need to implement the Mapping ABC. Something along the lines of this:

from collections.abc import Mapping


class C(Mapping):

    id=int()
    name=str()

    def __init__(self, id, name):
        self.id = id
        self.name = name

    def __iter__(self):
        for x in self.__dict__.keys():
            yield x

    def __len__(self):
        return len(self.__dict__)

    def __getitem__(self, key):
        return self.__dict__[key]

This way you should just be able to use s = '{id}{name}'.format(**c) rather than s = '{id}{name}'.format(**c.__dict__)

You can also use MutableMapping from collections.abc module if you want to be able to change your class variables like in a dictionary. MutableMapping would also require the implementation of __setitem__ and __delitem__

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM