38

属性を割り当てることができるネイキッドオブジェクトを作成する最も簡単な方法は何ですか?

具体的なユースケースは次のとおりです。Djangoオブジェクトインスタンスでさまざまな操作を行っていますが、インスタンスがNoneである場合があります(インスタンス上にあります)。この場合、属性に値を割り当てることができるように、可能な限り単純な偽のオブジェクトを作成したいと思います(例myobject.foo = 'bar')。

基本的に、私はこのJavascriptに相当するPythonを探しています。

myobject = {}
myobject.foo = 'bar'

私はこれにモックオブジェクト/ライブラリを使用できることを知っていますが、非常に単純なソリューション(上記のJavascriptと同じくらい単純)を望んでいます。ネイキッドオブジェクトインスタンスを作成する方法はありますか?何かのようなもの:

myobject = object()
myobject.foo = 'bar'
4

12 に答える 12

45

最初に単純なクラスを作成する必要があります。

class Foo(object):
    pass

myobject = Foo()
myobject.foo = 'bar'

あなたはそれをこのようにワンライナーにすることができます:

myobject = type("Foo", (object,), {})()
myobject.foo = 'bar'

to関数の呼び出しは、前のステートメントtypeと同じです。class

あなたが本当に最小限になりたいのなら...

myobject = type("", (), {})()

重要なのは、組み込みの型(やなどlistobjectはユーザー定義の属性をサポートしていないため、classステートメントまたはの3パラメーターバージョンの呼び出しを使用して型を作成する必要があるということですtype

于 2012-05-30T20:20:38.777 に答える
23

Python> = 3.3を使用している場合は、いつでもSimpleNamespaceを使用できます。これはPythontypesモジュールに含まれています。

SimpleNamespacereprは、同等性のテストも無料で受けられるので素晴らしいですどちらも、ミニマリストのオブジェクトにも役立つ可能性があります。

OPの質問でJavaScriptを翻訳すると、次のようになります。

from types import SimpleNamespace

myobject = SimpleNamespace() # myobject = {}
myobject.foo = 'bar'

SimpleNamespaceをインスタンス化するときにキーワード引数を使用することもできます。これらの引数は、インスタンス化されたSimpleNamespaceの属性になります。

p = SimpleNamespace(name='gary')
p.age = 32
p # => namespace(age=32, name='gary')

したがって、辞書をSimpleNamespaceオブジェクトに変換するための迅速で簡単な方法 (辞書キーが適切な識別子である場合)は、次のように簡単です。

d = {
    'name': 'gary',
    'age': 33 # had a birthday. 
}
p = SimpleNamespace(**d)

Python> = 3.7に、基本的に「<strong>可変の名前付きタプル」であるデータクラスがあります。これは、データオブジェクトがたくさんある場合に使用したいものかもしれません。

于 2018-03-22T20:47:42.510 に答える
7

Bunchモジュールを使用します。

sudo pip install bunch

dict.key束は、構文を介してそのコンテンツにアクセスできるようにする辞書です。

そして、そのように:

from bunch import Bunch
b = Bunch()
b.foo = "Bar"


b["foo2"] = "Bar2"
print b
>> Bunch(foo='Bar', foo2='Bar2')
b["foo"] = "Baz"
print b
>> Bunch(foo='Baz', foo2='Bar2')
于 2012-05-30T20:30:24.780 に答える
4
class NakedObject(object):
    pass

myobject = NakedObject()
myobject.foo = 'bar'
于 2012-05-30T20:20:50.477 に答える
4

私は非常に遅くここに来ますが、namedtuplesこの種のことを達成する誰も言及していないことに驚いています:

Foo = namedtuple('Foo', ['x'])
f = Foo(x='myattribute')
f.x
于 2016-04-12T17:59:41.043 に答える
2

Python 3の場合、

class Obj: pass

o = Obj()
o.name = 'gary'
o.age = 32

o
# <__main__.Obj at 0x17235ca65c0>

o.__dict__
# {'name': 'gary', 'age': 32}
于 2018-06-04T11:52:33.510 に答える
2

関数はPython3で属性を持つことができます。ネイキッドクラスと比較して、コードの1行全体を節約できます。

naked = lambda: None
naked.foo = 'bar'
于 2018-07-01T19:16:51.353 に答える
1

最初にこのようにオブジェクトをサブクラス化する必要があります...

class Myobject(object):
    pass

myobject1 = Myobject()
myobject1.foo = 'bar'
于 2012-05-30T20:19:55.370 に答える
0

おそらくあなたはこのようなものを探しています:

myobject={}
myobject['foo']='bar'

次に、次のように呼び出すことができます。

print myobject['foo']

または、これにクラスオブジェクトを使用できます。

class holder(object):
    pass

次に、次のようなものを使用できます。

hold=holder()
hold.myobject='bar'
print hold.myobject
于 2012-05-30T20:19:08.197 に答える
0

@PsychicOakの回答に従って、おそらくdictを使用する必要があります。

ただし、操作できるオブジェクトが本当に必要な場合は、次を試してください。

class FooClass(object): pass

FooClassその後、必要に応じて、それ自体またはインスタンスに属性を割り当てることができます。

于 2012-05-30T20:21:19.027 に答える
0

私は通常、クラスにnullオブジェクトを作成することを好みます。

class User(Model):
    username = CharField()
    password = CharField()


NONE_USER = User(username='', password='')

それから私はあなたの裸の物を使うところにそれを使います。

于 2012-05-30T20:34:13.990 に答える
0

場合によっては、を拡張するとdict役立つことがあります

お気に入り:

class SpecificModelData(dict):
   pass
   ...

class Payload(dict):
   ... enter code here

なぜdict?シリアライザーと一緒にうまく機能します。

なぜ新しいクラス?-それはあなたに名前と新しいタイプを与えます

于 2021-12-02T15:29:19.547 に答える