考慮內存的使用,時鐘週期或Python的好作風是它更好地做到這一點:最好是返回一個匿名類或一個對象用作'結構'?
def func():
class A:
x = 10
y = 20
return A
或本
def func():
o = object()
o.x = 10
o.y = 20
return o
還是別的什麼?我不想返回字典,因爲我不喜歡使用方括號。
考慮內存的使用,時鐘週期或Python的好作風是它更好地做到這一點:最好是返回一個匿名類或一個對象用作'結構'?
def func():
class A:
x = 10
y = 20
return A
或本
def func():
o = object()
o.x = 10
o.y = 20
return o
還是別的什麼?我不想返回字典,因爲我不喜歡使用方括號。
我喜歡用特殊的方法制作一個dict
的子類,我發現here。它看起來像:
class Struct(dict):
"""Python Objects that act like Javascript Objects"""
def __init__(self, *args, **kwargs):
super(Struct, self).__init__(*args, **kwargs)
self.__dict__ = self
這個對象可以這樣使用:
o = Struct(x=10)
o.y = 20
o['z'] = 30
print o.x, o['y'], o.z
不同類型的接入可以在一個可更換的方式使用。
我使用字典這樣的事情。 Dics有很多好處,比如列出所有按鍵等。
通常的技巧是使用namedtuple。
聽起來像是你想有一個namedtuple
(但它有效地只讀):
from collections import namedtuple
XYTuple = namedtuple('XYTuple', 'x y')
nt = XYTuple._make((10, 20))
print nt.x, nt.y
第二種解決方案不起作用:
>>> o = object()
>>> o.x = 10
AttributeError: 'object' object has no attribute 'x'
這是因爲對象的實例沒有__dict__
。
我同意使用方括號來訪問屬性並不優雅。返回一個值對象,我的團隊使用這個(這些代碼肯定可以改善):
class Struct(object):
"""
An object whose attributes are initialized from an optional positional
argument or from a set of keyword arguments (the constructor accepts the
same arguments than the dict constructor).
"""
def __init__(self, *args, **kwargs):
self.__dict__.update(*args, **kwargs)
def __repr__(self):
klass = self.__class__
attributes = ', '.join('{0}={1!r}'.format(k, v) for k, v in self.__dict__.iteritems())
return '{0}.{1}({2})'.format(klass.__module__, klass.__name__, attributes)
使用Struct
,你的例子可以改寫爲是:
def func():
return Struct(x = 10, y = 20)
的Struct
超過namedtuple
優勢是你不必事先定義你的類型。例如,它與JavaScript等語言中使用的內容更接近。 namedtuple
的優點是效率更高,同時可以通過索引或名稱訪問屬性。
如果某些屬性名稱不是字符集[_a-zA-Z0-9]中的有效標識符,我也喜歡@glglgl的優雅實現。 – 2012-07-20 11:18:49
然而,從[現在是當前]版本的jsobect
派生出的另一方式,也在@ glglgl的answer使用(但有很大的不同):
class Struct(dict):
def __getattr__(self, k):
try:
return self[k]
except KeyError:
return self.__getitem__(k)
def __setattr__(self, k, v):
if isinstance(v, dict):
self[k] = self.__class__(v)
else:
self[k] = v
o = Struct(x=10)
o.y = 20
o['z'] = 30
print(o.x, o['y'], o.z) # -> (10, 20, 30)
print(o['not_there']) # -> KeyError: 'not_there'
print(o.not_there) # -> KeyError: 'not_there'
優雅!這在我的「snippets」目錄中消失了。謝謝! +1 – 2012-07-20 11:21:20
真的很好。保存爲片段 – 2012-07-20 11:38:31
太棒了!這正是我需要的。 – 2012-07-20 12:12:35