51

JavaScriptにはオブジェクトリテラルがあります。

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

.NETには匿名タイプがあります。

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

名前付き引数を(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)

使用法:

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

しかし、この種のコードはPythonicと見なされますか?

4

8 に答える 8

73

なぜ辞書を使わないのですか?

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

print p
print p['name']
print p['age']
于 2010-07-26T13:39:40.860 に答える
43

名前付きタプルの使用を検討しましたか?

dict表記を使用する

>>> 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)

ラムダに相当するものは

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

個人的には、「匿名」関数に名前を付けるのはばかげていると思います

于 2010-07-26T13:46:09.833 に答える
14

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
于 2010-07-26T14:22:59.960 に答える
3

「匿名」のクラス/インスタンスを作成しても問題はありません。多くの場合、1行のコードで単純な関数呼び出しを使用して作成すると非常に便利です。私は個人的に次のようなものを使用します:

def make_class( *args, **attributes ):
    """With fixed inability of using 'name' and 'bases' attributes ;)"""
    if len(args) == 2:
        name, bases = args
    elif len(args) == 1:
        name, bases = args[0], (object, )
    elif not args:
        name, bases = "AnonymousClass", (object, )
    return type( name, bases, attributes )

obj = make_class( something = "some value" )()
print obj.something

ダミーオブジェクトを作成する場合は、問題なく機能します。Namedtupleは問題ありませんが、不変であるため、不便な場合があります。そして辞書は...まあ、辞書ですが__getattr__、の代わりに定義されたものを渡さなければならない状況があります__getitem__

それがpythonicであるかどうかはわかりませんが、それは時々物事をスピードアップし、私にとってはそれを使用するのに十分な理由です(時々)。

于 2010-07-26T17:10:47.417 に答える
1

JavaScriptではオブジェクトリテラルが理にかなっていると思います。理由は次の2つです。

  1. JavaScriptでは、オブジェクトはstring-indexプロパティを持つ「もの」を作成する唯一の方法です。Pythonでは、別の回答で述べられているように、辞書タイプがそれを行います。

  2. JavaScriptのオブジェクトシステムはプロトタイプベースです。JavaScriptにはクラスのようなものはありません(将来のバージョンで提供される予定ですが)—オブジェクトにはクラスではなくプロトタイプオブジェクトがあります。したがって、すべてのオブジェクトは組み込みのルートオブジェクトのみをプロトタイプとして必要とするため、リテラルを介して「何もないところから」オブジェクトを作成するのは自然なことです。Pythonでは、すべてのオブジェクトにクラスがあります。1回限りではなく、複数のインスタンスがある場合にオブジェクトを使用することが期待されます。

したがって、いいえ、オブジェクトリテラルはPythonicではありませんが、JavaScripthonicです。

于 2010-07-26T15:17:08.363 に答える
1

ほとんどの場合、単純な辞書で十分です。

リテラルの場合に指定したものと同様のAPIを探している場合でも、辞書を使用して、特殊__getattr__関数をオーバーライドするだけで済みます。

class CustomDict(dict):
    def __getattr__(self, name):
        return self[name]

p = CustomDict(user='James', location='Earth')
print p.user
print p.location

:namedtuplesとは異なり、フィールドは検証されず、引数が正しいことを確認する必要があることに注意してください。などの引数p['def'] = 'something'は辞書内で許容されますが、を介してそれらにアクセスすることはできませんp.def

于 2010-07-26T17:11:59.413 に答える
1

Python IAQから:

Python 2.3以降、構文を使用できます

dict(a=1, b=2, c=3, dee=4)

私に関する限り、これで十分です。Python 2.3 より前は、1 行関数を使用していました

def Dict(**dict): return dict
于 2010-07-26T15:03:25.380 に答える