考虑到内存使用,时钟周期或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
的子类,我发现在这里 。 看起来像:
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
不同类型的访问可以用更换的方式使用。
这个惯用的伎俩是使用namedtuple 。
听起来像是你想有一个namedtuple
(但它是有效只读):
from collections import namedtuple
XYTuple = namedtuple('XYTuple', 'x y')
nt = XYTuple._make( (10, 20) )
print nt.x, nt.y
我使用的字典这样的事情。 DICS有很多优惠,如列出所有键等。
第二种解决方案不起作用:
>>> 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
的优点是更有效和属性是通过在同一时间索引或名称访问。
然而,从[现在是当前]版本的衍生另一种方式jsobect
这也在@ glglgl的使用答案 (但有很大的不同):
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'