对象字面量在Python中是否符合规范?

53 投票
8 回答
30137 浏览
提问于 2025-04-16 01:50

JavaScript 有对象字面量,比如:

var p = {
  name: "John Smith",
  age:  23
}

而 .NET 有匿名类型,比如:

var p = new { Name = "John Smith", Age = 23}; // C#

在 Python 中,可以通过(稍微不太规范的方式)使用命名参数来模拟类似的东西:

class literal(object):
    def __init__(self, **kwargs):
        for (k,v) in kwargs.iteritems():
            self.__setattr__(k, v)
    def __repr__(self):
        return 'literal(%s)' % ', '.join('%s = %r' % i for i in sorted(self.__dict__.iteritems()))
    def __str__(self):
        return repr(self)

用法:

p = literal(name = "John Smith", age = 23)
print p       # prints: literal(age = 23, name = 'John Smith')
print p.name  # prints: John Smith

但是,这种写法算不算是 Python 风格呢?

8 个回答

16

来自 ActiveState:

class Bunch:
    def __init__(self, **kwds):
        self.__dict__.update(kwds)

# that's it!  Now, you can create a Bunch
# whenever you want to group a few variables:

point = Bunch(datum=y, squared=y*y, coord=x)

# and of course you can read/write the named
# attributes you just created, add others, del
# some of them, etc, etc:
if point.squared > threshold:
    point.isok = 1
74

为什么不直接用字典呢?

p = {'name': 'John Smith', 'age': 23}

print p
print p['name']
print p['age']
44

你有没有考虑过使用一种叫做 命名元组 的东西呢?

你可以用字典的方式来表示

>>> from collections import namedtuple
>>> L = namedtuple('literal', 'name age')(**{'name': 'John Smith', 'age': 23})

或者用关键字参数

>>> L = namedtuple('literal', 'name age')(name='John Smith', age=23)
>>> L
literal(name='John Smith', age=23)
>>> L.name
'John Smith'
>>> L.age
23

其实把这种行为封装成一个函数是很简单的

def literal(**kw):
    return namedtuple('literal', kw)(**kw)

用 lambda 表达式来写的话是这样的

literal = lambda **kw: namedtuple('literal', kw)(**kw)

不过我个人觉得给“匿名”函数起名字有点傻

撰写回答