对象文字是Pythonic吗?

Shi*_*oir 42 python object-literal

JavaScript有对象文字,例如

var p = {
  name: "John Smith",
  age:  23
}
Run Code Online (Sandbox Code Playgroud)

和.NET有匿名类型,例如

var p = new { Name = "John Smith", Age = 23}; // C#
Run Code Online (Sandbox Code Playgroud)

类似的东西可以通过(ab)使用命名参数在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)
Run Code Online (Sandbox Code Playgroud)

用法:

p = literal(name = "John Smith", age = 23)
print p       # prints: literal(age = 23, name = 'John Smith')
print p.name  # prints: John Smith
Run Code Online (Sandbox Code Playgroud)

但是这种代码被认为是Pythonic吗?

Way*_*ner 67

为什么不用字典呢?

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

print p
print p['name']
print p['age']
Run Code Online (Sandbox Code Playgroud)

  • 你也可以使用`dict`函数:`p = dict(name ='John Smith',age = 23)` (9认同)
  • 是的,当然 - 但是在测试/原型制作/玩乐时,在交互式翻译中做所有这些都有点矫枉过正.你知道你以后会明确地定义它,但是*现在*你想要达到目的...... (3认同)
  • 真实的故事.如果是这样的话,我会继续把这个功能放在一些"工具"文件和"来自工具导入文字"中,或者每当我在解释器中玩耍时都会这样 - 因为当你正在做的就是这样的时候,它就不会如果它是非常pythonic(很多人使用1个空间进行缩进 - 例如,在真实代码中明显不是pythonic),这非常重要.无论如何,拥有一个经常使用的python调整"工具箱"是一个好主意. (3认同)
  • 虽然我同意,但我认为在工作中存在哲学上的差异.Python中流行的哲学是,如果你需要一个带有`.name`和`.age`成员的对象,你应该显式创建该对象及其所有构造函数等. (2认同)

Joh*_*ooy 39

您是否考虑使用命名元组

使用你的字母表示法

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

或关键字参数

>>> L = namedtuple('literal', 'name age')(name='John Smith', age=23)
>>> L
literal(name='John Smith', age=23)
>>> L.name
'John Smith'
>>> L.age
23
Run Code Online (Sandbox Code Playgroud)

可以很容易地将此​​行为包装到函数中

def literal(**kw):
    return namedtuple('literal', kw)(**kw)
Run Code Online (Sandbox Code Playgroud)

lambda等价物

literal = lambda **kw: namedtuple('literal', kw)(**kw)
Run Code Online (Sandbox Code Playgroud)

但就个人而言,我认为给"匿名"功能命名是愚蠢的


pil*_*her 10

来自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
Run Code Online (Sandbox Code Playgroud)