Apa itu atribut pada python?

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

tetapi ini tidak berhasil.

Ada ide?

edit:

Saya mengatur atribut dari loop for yang loop melalui daftar nilai, mis.

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 fungsi setattr karena saya tidak tahu bagaimana melakukan obj.a.NAME dari loop for.

Bagaimana saya mengatur atribut berdasarkan nilai p pada contoh di atas?

Anda dapat menggunakan resep kuno Bunch 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:

obj = someobject
obj.a = lambda: None
setattr(obj.a, 'somefield', 'somevalue')

Apakah hilangnya kejelasan dibandingkan dengan resep Bunch yang terhormat itu OK, adalah keputusan gaya saya tentu saja akan menyerahkan kepada Anda.

Built-in object dapat instantiated tetapi tidak dapat menetapkan atribut apa pun di dalamnya. (Saya berharap bisa, untuk tujuan yang tepat ini.) Tidak memiliki __dict__ untuk menyimpan atribut.

Saya biasanya hanya melakukan ini:

class Object(object):
    pass

a = Object()
a.somefield = somevalue

Ketika saya bisa, saya memberi kelas Object nama yang lebih bermakna, tergantung pada data apa yang saya masukkan di dalamnya.

Beberapa orang melakukan hal yang berbeda, di mana mereka menggunakan sub-kelas dict yang memungkinkan akses atribut untuk mendapatkan kunci. (d.key bukan d['key'])

Edit : Untuk tambahan pertanyaan Anda, menggunakan setattr tidak masalah. Anda tidak bisa menggunakan setattr pada contoh object().

params = ['attr1', 'attr2', 'attr3']
for p in params:
    setattr(obj.a, p, value)

Ada beberapa cara untuk mencapai tujuan ini ... Pada dasarnya Anda membutuhkan objek yang dapat diperpanjang.

obj.a = type('Test', (object,), {})  
obj.a.b = 'fun'  

obj.b = lambda:None

class Test:
  pass
obj.c = Test()

Sekarang Anda bisa melakukannya (tidak yakin apakah itu jawaban yang sama dengan evilpie):

MyObject = type('MyObject', (object,), {})
obj = MyObject()
obj.value = 42

Modul mock pada dasarnya dibuat untuk itu.

import mock
obj = mock.Mock()
obj.a = 5

Coba kode di bawah ini:

$ python
>>> class Container(object):
...     pass 
...
>>> x = Container()
>>> x.a = 10
>>> x.b = 20
>>> x.banana = 100
>>> x.a, x.b, x.banana
(10, 20, 100)
>>> dir(x)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', 
'__getattribute__', '__hash__', '__init__', '__module__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__',     '__sizeof__', 
'__str__', '__subclasshook__', '__weakref__', 'a', 'b', 'banana']

sebagai docs say :

Catatan: object tidak tidak memiliki __dict__, sehingga Anda tidak dapat menetapkan atribut arbitrer ke turunan dari kelas object.

Anda bisa menggunakan instance kelas dummy.

Anda juga dapat menggunakan objek kelas secara langsung; itu menciptakan namespace:

class a: pass
a.somefield1 = 'somevalue1'
setattr(a, 'somefield2', 'somevalue2')

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

In [11]: auth = type('', (), {})
In [12]: auth.func = staticmethod(lambda i: i * 2)
In [13]: auth.func(2)
Out[13]: 4

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.

# python 2.7

class NestedObject():
    def __init__(self, initial_attrs):
        for key in initial_attrs:
            setattr(self, key, initial_attrs[key])

obj = someobject
attributes = { 'attr1': 'val1', 'attr2': 'val2', 'attr3': 'val3' }
obj.a = NestedObject(attributes)
>>> obj.a.attr1
'val1'
>>> obj.a.attr2
'val2'
>>> obj.a.attr3
'val3'

Kami juga dapat mengizinkan argumen kata kunci. Lihat posting ini . 

class NestedObject(object):
    def __init__(self, *initial_attrs, **kwargs):
        for dictionary in initial_attrs:
            for key in dictionary:
                setattr(self, key, dictionary[key])
        for key in kwargs:
            setattr(self, key, kwargs[key])


obj.a = NestedObject(attr1='val1', attr2='val2', attr3= 'val3')

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

import os

def x_path(path_name):
    return getattr(x_path, path_name)

x_path.root = '/home/x'
for name in ['repository', 'caches', 'projects']:
    setattr(x_path, name, os.path.join(x_path.root, name))

Ini keren karena sekarang:

In [1]: x_path.projects
Out[1]: '/home/x/projects'

In [2]: x_path('caches')
Out[2]: '/home/x/caches'

Jadi ini menggunakan objek fungsi seperti jawaban di atas tetapi menggunakan fungsi untuk mendapatkan nilai (Anda masih dapat menggunakan (getattr, x_path, 'repository') daripada x_path('repository') jika Anda mau).

Objek mana yang Anda gunakan? Baru saja mencobanya dengan kelas sampel dan berhasil:

class MyClass:
  i = 123456
  def f(self):
    return "hello world"

b = MyClass()
b.c = MyClass()
setattr(b.c, 'test', 123)
b.c.test

Dan saya mendapat 123 sebagai jawabannya.

Satu-satunya situasi di mana saya melihat kegagalan ini adalah jika Anda mencoba setattr pada objek bawaan.

Pembaruan: Dari komentar ini adalah pengulangan dari: Mengapa Anda tidak dapat menambahkan atribut ke objek dengan python?

Apa itu objek dalam Python?

Objek pada python adalah kumpulan dari variabel-variabel (dinamakan atribut) dan kumpulan dari fungsi-fungsi (dinamakan perilaku). Atas definisi itu, maka semua hal di dalam python adalah sebuah Objek. Objek dan Kelas dalam python bermakna sama.

Apa yang dimaksud dengan atribut dalam OOP?

Istilah Dalam OOP Atribut adalah data anggota (variabel kelas dan variabel contoh) dan metode, diakses melalui notasi titik. Sebuah variabel yang dibagi oleh semua contoh kelas.

Apa itu namespace pada Python?

Sebuah namespace adalah pemetaan dari nama ke objek. Sebagian besar ruang nama namespace saat ini diimplementasikan sebagai kamus dictionary Python, tetapi itu biasanya tidak terlihat dengan cara apa pun (kecuali untuk kinerja), dan itu mungkin berubah di masa depan.

Apa yang dimaksud dengan class pada Python?

Apa itu class method pada python? Class method pada python adalah method statis yang disandarkan langsung kepada sebuah kelas, artinya kita bisa memanggil fungsi tersebut tanpa harus membuat objek terlebih dahulu [1].