2012-05-04 41 views
1

任何人都可以舉個例子嗎?如何將「namedtuples」更改爲python中的類?

在類和namedtuples中使用變量有什麼區別?

+1

'namedtuple'動態生成對飛類。 – Daenyth

+0

由於你顯然從來沒有得到一個可以接受的答案,也許你可以更新你的問題,並提供一些額外的信息。一般類實例和一個已命名的實例之間的一個區別是後者是不可變的,就像元組一樣 - 意味着你不能在不替換整個結構的情況下改變其任何屬性的值。 – martineau

回答

7

返回值namedtuple一類。沒有黑暗的魔法。你不需要將一個命名的「返回」轉換爲一個類;它完全返回。

namedtuple創建一個繼承自__builtin__.tuple的新類。當你調用namedtuple('Point', 'x y')(1, 0),你得到的是元組對象(1, 0)具有以下語法糖:

  • 一個__dict__映射,其中{'x': 1, 'y', 0}
  • 兩個屬性xy分別致電__getitem__(0)__getitem__(1)
  • 一個__repr__方法返回'Point(x=1, y=0)'
比這

其他,它只是一個元組對象。它的屬性和屬性數量是不可變的。

不過,我懷疑你的意思是你想利用nametuple('Point', 'x, y'),而是獲得:

class Point: 
    def __init__(x, y): 
     self.x = x 
     self.y = y 

在這種情況下,你在不當nametuple,而應使用type

def init(self, x, y): 
    self.x, self.y = x, y 
Point = type('Point', (object,), {'__init__': init}) 
+0

你錯了。當你調用'namedtuple'('Point','x y')(1,0)'你不**得到元組對象。你得到'Point'實例。也沒有'__dict__'映射。而'x'和'y'屬性**不會**調用'__dict __ [..]'。 – akaRem

+1

@akaRem WRT namedtuple('Point','x y'),它返回一個繼承元組的類,正如我寫的。我不確定你在哪裏與我不同意。請澄清? – Jjed

+0

@akaRem查看[源文件](http://hg.python.org/cpython/file/default/Lib/collections/__init__.py)字段屬性調用\ _ \ _ getitem \ _ \ _ s,所以你'在那裏改正。然而,\ _ \ _ dict \ _ \ _明確定義爲_fields到元組數據的映射。來自'class {typename}(tuple)的 – Jjed

2

很模糊題。

我想你的意思是結構類似

myPoint1 = namedtuple('myPoint1','x y') 

class myPoint2(object): 
    __slots__ = ['x','y'] 
    def __init__(self, x, y) 
     self.x = x 
     self.y = y 

myPoint1是在訪問速度更快的索引my_point1[0]my_point1[1](其中0代表x,並1代表y)。但它attr所my_point1.xmy_point1.y在訪問慢,因爲雙查找和附加功能執行(見源 - 這是很documentated如何做namedtuple工作)

myPoint2只有accessable attr所my_point2.xmy_point2.y。而訪問attr myPoint2比訪問attr myPoint1更快。

此外,如果你不使用__slots__,因爲ATTRS /方法字典爲每個實例創建的每個實例都將佔用更多的內存(用於動態調整它們 - 添加或刪除ATTRS,字段,方法等),是否插槽僅爲類創建一次。

不久,namedtuple返回tuple subclass,通常作爲tuple工作,但哪些數據也可以通過指定的attrs訪問。

0

我認爲OP想要對目前名爲tuple的數據結構的類定義進行說明。 namedtuple([...], verbose=True)可能是你在找什麼:

>>> 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') 
0

從收藏導入namedtuple作爲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()) 
+0

這究竟是如何解決這個問題的,這是關於類和變量類中變量之間的區別的? – MrT

+0

我相信這是問題的標題:如何將「namedtuples」更改爲python中的類? – Chuma

相關問題