Can anyone give an example?
What's the difference between using variables in classes and in namedtuples?
The return value of namedtuple
is a class. No dark magic. You do not need to "convert" a namedtuple return into a class; it returned exactly that.
namedtuple
creates a new class that inherits from __builtin__.tuple
. When you call namedtuple('Point', 'x y')(1, 0)
, you're getting is the tuple object (1, 0)
with the following syntactic sugar:
__dict__
mapping where {'x': 1, 'y', 0}
x
and y
that call __getitem__(0)
and __getitem__(1)
respectively.__repr__
method that returns 'Point(x=1, y=0)'
Other than this, it's just a tuple object. Its attributes and number of attributes are immutable.
However, I suspect you mean you want to take nametuple('Point', 'x, y')
and instead get:
class Point:
def __init__(x, y):
self.x = x
self.y = y
In this case you are misusing nametuple
, and should instead be using type
:
def init(self, x, y):
self.x, self.y = x, y
Point = type('Point', (object,), {'__init__': init})
Very vague question.
I suppose that you mean constructions like
myPoint1 = namedtuple('myPoint1','x y')
and
class myPoint2(object):
__slots__ = ['x','y']
def __init__(self, x, y)
self.x = x
self.y = y
myPoint1
is faster in access by index my_point1[0]
, my_point1[1]
(where 0
stands for x
, and 1
stands for y
). But it's slower in access by attr my_point1.x
, my_point1.y
because of double lookups and additional function executing (see source - it's well documentated about how does namedtuple
work)
myPoint2
is only accessable by attr my_point2.x
, my_point2.y
. And accessing by attr myPoint2
is faster than accessing by attr myPoint1
.
Also if you dont use __slots__
, every instance would consume more memory because dict of attrs/methods is created for every instance (for dynamically tune them - add or remove attrs, fields, methods, etc), whether slots is created once for class only.
Shortly, namedtuple
returns tuple subclass
that commonly works as tuple
, but which data is also accessable by specified attrs.
I think OP wants to be explit about the class definition for a data structure which is currently a namedtuple. namedtuple([...], verbose=True)
is likely what you're looking for:
>>> from collections import namedtuple
>>> Pooper = namedtuple('Pooper', ('poop_length','poop_width'))
>>> Pooper(7.5, 1.5)
Pooper(poop_length=7.5, poop_width=1.5)
>>> Pooper = namedtuple('Pooper', ('poop_length','poop_width'), verbose=True)
class Pooper(tuple):
'Pooper(poop_length, poop_width)'
__slots__ = ()
_fields = ('poop_length', 'poop_width')
def __new__(_cls, poop_length, poop_width):
'Create new instance of Pooper(poop_length, poop_width)'
return _tuple.__new__(_cls, (poop_length, poop_width))
@classmethod
def _make(cls, iterable, new=tuple.__new__, len=len):
'Make a new Pooper 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 __repr__(self):
'Return a nicely formatted representation string'
return 'Pooper(poop_length=%r, poop_width=%r)' % self
def _asdict(self):
'Return a new OrderedDict which maps field names to their values'
return OrderedDict(zip(self._fields, self))
def _replace(_self, **kwds):
'Return a new Pooper object replacing specified fields with new values'
result = _self._make(map(kwds.pop, ('poop_length', 'poop_width'), _self))
if kwds:
raise ValueError('Got unexpected field names: %r' % kwds.keys())
return result
def __getnewargs__(self):
'Return self as a plain tuple. Used by copy and pickle.'
return tuple(self)
__dict__ = _property(_asdict)
def __getstate__(self):
'Exclude the OrderedDict from pickling'
pass
poop_length = _property(_itemgetter(0), doc='Alias for field number 0')
poop_width = _property(_itemgetter(1), doc='Alias for field number 1')
from collections import namedtuple as nt
human_nt = nt('Human_nt', 'name, age')
peter_nt = human_nt('Peter', 20)
class Human_cls (human_nt):
def some_methods(self):
pass
peter_cls = Human_cls(**peter_nt._asdict())
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.