1

考虑到内存使用、时钟周期或良好的 Pythonic 风格,最好这样做:

def func():
    class A:
       x = 10
       y = 20
    return A

或这个

def func():
    o = object()
    o.x = 10
    o.y = 20
    return o

或者是其他东西?我不想返回字典,因为我不喜欢使用方括号。

4

6 回答 6

9

我喜欢使用一种特殊的方式来制作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

可以以可交换的方式使用不同类型的访问。

于 2012-07-20T11:07:04.073 回答
4

通常的技巧是使用namedtuple

于 2012-07-20T11:04:45.867 回答
3

听起来你想要一个namedtuple(但它实际上是只读的):

from collections import namedtuple

XYTuple = namedtuple('XYTuple', 'x y')
nt = XYTuple._make( (10, 20) )

print nt.x, nt.y
于 2012-07-20T11:07:48.220 回答
2

我用 dict 来处理这样的事情。Dics 有很多好处,例如列出所有键等。

于 2012-07-20T10:59:10.927 回答
1

第二种解决方案不起作用:

>>> o = object()
>>> o.x = 10
AttributeError: 'object' object has no attribute 'x'

这是因为 object 的实例没有__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)

Structover的优点namedtuple是您不必事先定义类型。例如,它更接近于您在 JavaScript 等语言中使用的内容。namedtuple具有更高效的优点,并且属性可以同时通过索引或名称访问。

于 2012-07-20T11:11:44.770 回答
1

jsobect@glglgl 的答案中也使用了从 [now current] 版本派生的另一种方式(但非常不同):

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'
于 2017-10-17T20:33:36.900 回答