Saya ingin membuat objek dinamis (di dalam objek lain) dengan Python dan kemudian menambahkan atribut padanya.
Saya mencoba:
obj = someobject
obj.a = object()
setattr(obj.a, 'somefield', 'somevalue')
tapi ini tidak berhasil.
Ada ide?
edit:
Saya mengatur atribut dari for
loop yang loop melalui daftar nilai, misalnya
params = ['attr1', 'attr2', 'attr3']
obj = someobject
obj.a = object()
for p in params:
obj.a.p # where p comes from for loop variable
Dalam contoh di atas saya akan mendapatkan obj.a.attr1
, obj.a.attr2
, obj.a.attr3
.
Saya menggunakan setattr
fungsi ini karena saya tidak tahu bagaimana melakukannya obj.a.NAME
dari satu for
lingkaran.
Bagaimana saya mengatur atribut berdasarkan nilai p
pada contoh di atas?
python
class
object
attributes
John
sumber
sumber
a = object()
dan Anda perluobj.a = object()
. Sekali lagi saya berbicara tentang contohnya, dalam kode aktual Anda sebuah objek di dalam objek mungkin berguna.Jawaban:
Anda bisa menggunakan resep Bunch kuno saya , tetapi jika Anda tidak ingin membuat "kelas banyak", yang sangat sederhana sudah ada di Python - semua fungsi dapat memiliki atribut yang berubah-ubah (termasuk fungsi lambda). Jadi, karya-karya berikut:
Apakah kehilangan kejelasan dibandingkan dengan
Bunch
resep terhormat itu baik-baik saja, adalah keputusan gaya tentu saja akan saya serahkan kepada Anda.sumber
lambda: 23
), sehingga untuk para pakar seperti itu menggunakanlambda
s untuk tujuan ini mungkin akan terasa seperti "hack". Secara pribadi, saya tidak terlalu sukalambda
dengan Python - tapi itu masalah pribadi.lambda
pola cocok untuk kasus penggunaan Anda atau tidak dapat mengarahkan Anda untuk menyadari bahwa sesuatu yang awalnya Anda anggap sebagai data sebenarnya lebih mirip fungsi - atau, dalam hal apa pun, functor.from argparse import Namespace
meskipun saya berharap itu tinggal di tempat lain * misalnya,collection
) - lagi menggunakan kembali jenis yang sudah ada, hanya yang lebih baik, dan masih menghindari penciptaan jenis baru. Tapi, itu tidak ada di sana :-).Built-in
object
dapat dipakai tapi tidak dapat memiliki atribut yang ditetapkan di dalamnya. (Saya berharap itu bisa, untuk tujuan yang tepat ini.) Ia tidak perlu__dict__
memiliki atribut.Saya biasanya hanya melakukan ini:
Ketika saya bisa, saya memberi
Object
kelas nama yang lebih bermakna, tergantung pada data apa yang saya masukkan.Beberapa orang melakukan hal yang berbeda, di mana mereka menggunakan sub-kelas
dict
yang memungkinkan akses atribut untuk mendapatkan kunci. (d.key
bukannyad['key']
)Sunting : Untuk tambahan pertanyaan Anda, menggunakan
setattr
tidak apa-apa. Anda tidak bisa menggunakansetattr
padaobject()
contoh.sumber
foo = object()
bekerja, tetapi Anda tidak bisa melakukan banyak hal dengan itutype....
atau lambda tidak pernah menjadi favorit saya, seperti teks muntah dalam kode saya. Tapi ide ini bagus untuk menggunakan objek untuk menyimpan properti. Meninggalkan kode lebih dapat dibaca b / c ketika saya melihat lambda Saya memperlambat pembacaan saya hingga 25% sementara cara Anda masuk akal! Terima kasih.Struct
nama kelas untuk membuatnya lebih jelas. Menghemat saya mengetik["
dan"]
, Cheers!Ada
types.SimpleNamespace
kelas di Python 3.3+ :collections.namedtuple
,typing.NamedTuple
bisa digunakan untuk benda yang tidak bisa diubah. PEP 557 - Kelas Data menyarankan alternatif yang bisa berubah.Untuk fungsionalitas yang lebih kaya, Anda bisa mencoba
attrs
paket . Lihat contoh penggunaan .sumber
argparse.Namespace
kelasattrs
Paket @Roel mendukung Python 2.7Ada beberapa cara untuk mencapai tujuan ini. Pada dasarnya Anda membutuhkan objek yang dapat diperpanjang.
sumber
obj.a = type('', (), {})
The
mock
modul pada dasarnya dibuat untuk itu.sumber
unittest.Mock
adalah bagian dari perpustakaan standar sejak Python 3.3 ( docs.python.org/3/library/unittest.mock.html )mock
di dalamnya. Rasanya aneh bagiku.Sekarang Anda bisa melakukannya (tidak yakin apakah itu jawaban yang sama dengan evilpie):
sumber
Coba kode di bawah ini:
sumber
Anda juga dapat menggunakan objek kelas secara langsung; itu menciptakan namespace:
sumber
seperti kata docs :
Anda bisa menggunakan instance kelas dummy.
sumber
Solusi ini sangat membantu selama pengujian. Membangun jawaban orang lain, saya melakukan ini di Python 2.7.9 (tanpa metode statis saya mendapatkan TypeError (metode tidak terikat ...):
sumber
Objek mana yang Anda gunakan? Baru saja mencobanya dengan kelas sampel dan berhasil:
Dan saya mendapat
123
jawabannya.Satu-satunya situasi di mana saya melihat kegagalan ini adalah jika Anda mencoba
setattr
objek bawaan.Pembaruan: Dari komentar ini adalah pengulangan: Mengapa Anda tidak dapat menambahkan atribut ke objek dengan python?
sumber
Datang ke ini pada sore hari tetapi di sini adalah pennyworth saya dengan objek yang kebetulan memegang beberapa jalur yang berguna dalam aplikasi tetapi Anda dapat mengadaptasinya untuk apa pun di mana Anda ingin sedikit informasi yang dapat Anda akses dengan getattr dan notasi titik (yang menurut saya pertanyaan ini sebenarnya tentang):
Ini keren karena sekarang:
Jadi ini menggunakan objek fungsi seperti jawaban di atas tetapi menggunakan fungsi untuk mendapatkan nilai (Anda masih bisa menggunakan
(getattr, x_path, 'repository')
daripadax_path('repository')
jika Anda suka).sumber
Jika kita dapat menentukan dan menggabungkan semua atribut dan nilai sebelum membuat objek bersarang, maka kita bisa membuat kelas baru yang menggunakan argumen kamus tentang pembuatan.
Kami juga dapat mengizinkan argumen kata kunci. Lihat posting ini .
sumber
sumber
Cara lain yang saya lihat, seperti ini:
sumber
class a: pass
memberikan semua daya yang dibutuhkan.