Relevance of typename in namedtuple

前端 未结 3 769
-上瘾入骨i
-上瘾入骨i 2020-12-15 16:11
from collections import namedtuple

Point = namedtuple(\'whatsmypurpose\',[\'x\',\'y\'])
p = Point(11,22)
print(p)

Output:

whatsmyp         


        
相关标签:
3条回答
  • 2020-12-15 16:16

    Consider:

    class MyClass(tuple):
       pass
    

    This creates a type, which is a tuple subclass, and it has a name MyClass.__name__ == "MyClass". namedtuple is a type factory, it also creates tuple subclasses, but in this functional API you have to pass the name explicitly.

    When you assign the returned type to a different name:

    Point = namedtuple('whatsmypurpose',['x','y'])
    

    It is similar to doing this:

    class whatsmypurpose(tuple):
        ... # extra stuff here to setup slots, field names, etc
    
    Point = whatsmypurpose
    del whatsmypurpose
    

    In both cases you are just aliasing a different name to the type.

    Usually you would assign to the same name as used for the type name. If you are bothered that repeating the same string is not DRY, then you can use the declarative API in typing.NamedTuple instead of that functional API in collections. Then you can be bothered by needing to annotate types, instead.

    0 讨论(0)
  • 2020-12-15 16:21

    'whatsmypurpose' gives the new subclass its type name. From the docs:

    collections.namedtuple(typename, field_names, verbose=False,rename=False)
    Returns a new tuple subclass named typename.

    Here is an example:

    >>> from collections import namedtuple
    >>> Foo = namedtuple('Foo', ['a', 'b'])
    >>> type(Foo)
    <class 'type'>
    >>> a = Foo(a = 1, b = 2)
    >>> a
    Foo(a=1, b=2)
    >>> Foo = namedtuple('whatsmypurpose', ['a', 'b'])
    >>> a = Foo(a = 1, b = 2)
    >>> a
    whatsmypurpose(a=1, b=2)
    >>> 
    

    Set the verbose parameter to True and you can see the complete whatsmypurpose class definition.

    >>> Foo = namedtuple('whatsmypurpose', ['a', 'b'], verbose=True)
    from builtins import property as _property, tuple as _tuple
    from operator import itemgetter as _itemgetter
    from collections import OrderedDict
    
    class whatsmypurpose(tuple):
        'whatsmypurpose(a, b)'
    
        __slots__ = ()
    
        _fields = ('a', 'b')
    
        def __new__(_cls, a, b):
            'Create new instance of whatsmypurpose(a, b)'
            return _tuple.__new__(_cls, (a, b))
    
        @classmethod
        def _make(cls, iterable, new=tuple.__new__, len=len):
            'Make a new whatsmypurpose object from a sequence or iterable'
            result = new(cls, iterable)
            if len(result) != 2:
                raise TypeError('Expected 2 arguments, got %d' % len(result))
            return result
    
        def _replace(_self, **kwds):
            'Return a new whatsmypurpose object replacing specified fields with new values'
            result = _self._make(map(kwds.pop, ('a', 'b'), _self))
            if kwds:
                raise ValueError('Got unexpected field names: %r' % list(kwds))
            return result
    
        def __repr__(self):
            'Return a nicely formatted representation string'
            return self.__class__.__name__ + '(a=%r, b=%r)' % self
    
        def _asdict(self):
            'Return a new OrderedDict which maps field names to their values.'
            return OrderedDict(zip(self._fields, self))
    
        def __getnewargs__(self):
            'Return self as a plain tuple.  Used by copy and pickle.'
            return tuple(self)
    
        a = _property(_itemgetter(0), doc='Alias for field number 0')
    
        b = _property(_itemgetter(1), doc='Alias for field number 1')
    
    0 讨论(0)
  • namedtuple() is a factory function for tuple subclasses. Here, 'whatsmypurpose'is the type name. When you create a named tuple, a class with this name (whatsmypurpose) gets created internally.

    You can notice this by using the verbose argument like:

    Point=namedtuple('whatsmypurpose',['x','y'], verbose=True)
    

    Also you can try type(p) to verify this.

    0 讨论(0)
提交回复
热议问题