Iterate atas atribut objek di python

Aku punya python objek dengan beberapa atribut dan metode. Saya ingin iterate atas atribut objek.

class my_python_obj(object):
    attr1='a'
    attr2='b'
    attr3='c'

    def method1(self, etc, etc):
        #Statements

Saya ingin menghasilkan sebuah kamus yang berisi semua benda-benda atribut dan nilai saat ini, tapi saya ingin melakukannya dalam cara yang dinamis (jadi jika nanti saya tambahkan atribut lain saya don't harus ingat untuk memperbarui fungsi saya juga).

Dalam php variabel-variabel yang dapat digunakan sebagai tombol, tapi benda-benda di python adalah unsuscriptable dan jika saya menggunakan notasi titik untuk menciptakan atribut baru dengan nama saya var, yang tidak saya maksud.

Hanya untuk membuat hal-hal yang lebih jelas:

def to_dict(self):
    '''this is what I already have'''
    d={}
    d["attr1"]= self.attr1
    d["attr2"]= self.attr2
    d["attr3"]= self.attr3
    return d

·

def to_dict(self):
    '''this is what I want to do'''
    d={}
    for v in my_python_obj.attributes:
        d[v] = self.v
    return d

Update: Dengan atribut maksudku hanya variabel-variabel dari objek ini, bukan metode.

Mengomentari pertanyaan (2)
Larutan

Dengan asumsi anda memiliki kelas seperti

>>> class Cls(object):
...     foo = 1
...     bar = 'hello'
...     def func(self):
...         return 'call me'
...
>>> obj = Cls()

panggilan dir pada objek memberikan kembali semua atribut objek tersebut, termasuk python atribut khusus. Meskipun beberapa atribut objek adalah callable, seperti metode.

>>> dir(obj)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar', 'foo', 'func']

Anda selalu dapat menyaring metode khusus dengan menggunakan daftar pemahaman.

>>> [a for a in dir(obj) if not a.startswith('__')]
['bar', 'foo', 'func']

atau jika anda lebih memilih peta/filter.

>>> filter(lambda a: not a.startswith('__'), dir(obj))
['bar', 'foo', 'func']

Jika anda ingin menyaring metode, anda dapat menggunakan built-in callable sebagai cek.

>>> [a for a in dir(obj) if not a.startswith('__') and not callable(getattr(obj, a))]
['bar', 'foo']

Anda juga bisa memeriksa perbedaan antara class dan instance objek menggunakan.

>>> set(dir(Cls)) - set(dir(object))
set(['__module__', 'bar', 'func', '__dict__', 'foo', '__weakref__'])
Komentar (14)

secara umum menempatkan __iter__ metode dalam kelas dan iterate melalui atribut objek atau menempatkan ini mixin kelas di kelas anda.

class IterMixin(object):
    def __iter__(self):
        for attr, value in self.__dict__.iteritems():
            yield attr, value

Kelas anda:

>>> class YourClass(IterMixin): pass
...
>>> yc = YourClass()
>>> yc.one = range(15)
>>> yc.two = 'test'
>>> dict(yc)
{'one': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], 'two': 'test'}
Komentar (2)

Benda-benda di python toko atribut mereka (termasuk fungsi) dalam dict disebut __dict__. Anda dapat (tetapi umumnya tidak't) gunakan ini untuk mengakses atribut ini secara langsung. Jika anda hanya ingin daftar, anda bisa juga memanggil dir(obj), yang kembali iterable dengan semua atribut nama, yang anda kemudian bisa lolos ke getattr.

Namun, perlu melakukan apa-apa dengan nama-nama variabel biasanya desain yang buruk. Mengapa tidak menjaga mereka dalam koleksi?

class Foo(object):
    def __init__(self, **values):
        self.special_values = values

Anda kemudian dapat iterate atas tombol dengan kunci dalam obj.special_values:

Komentar (2)

Seperti yang disebutkan dalam beberapa jawaban/komentar sudah, Python benda-benda yang sudah menyimpan kamus atribut mereka (metode aren't termasuk). Hal ini dapat diakses sebagai __dict__, tapi cara yang lebih baik adalah dengan menggunakan var (output adalah sama, meskipun). Perhatikan bahwa mengubah kamus ini akan mengubah atribut pada contoh! Hal ini dapat berguna, tetapi juga berarti anda harus berhati-hati dengan bagaimana anda menggunakan kamus ini. Berikut ini's contoh cepat:

``python kelas A(): def init(self, x=3, y=2, z=5): mandiri.x = x mandiri._y = y self.z = z

def f(self): lulus

a = () cetak(var(a))

{'x': 3, '_y': 2, 'z': 5}

semua atribut dari a tapi tidak ada metode!

perhatikan bagaimana kamus ini selalu up-to-date

a.x = 10 cetak(var(a))

{'x': 10, '_y': 2, 'z': 5}

mengubah kamus memodifikasi contoh atribut

vars(a)["_y"] = 20 cetak(var(a))

{'x': 10, '_y': 20, 'z': 5}

``

Menggunakan dir(a) adalah aneh, jika tidak langsung yang buruk, pendekatan untuk masalah ini. It's baik jika anda benar-benar diperlukan untuk iterate melalui semua atribut dan metode kelas (termasuk metode khusus seperti __init__). Namun, hal ini tidak't tampaknya menjadi apa yang anda inginkan, dan bahkan jawaban yang diterima pergi tentang ini buruk dengan menerapkan beberapa rapuh penyaringan untuk mencoba untuk menghapus metode dan meninggalkan hanya satu atribut, anda dapat melihat bagaimana ini akan gagal untuk kelas A yang didefinisikan di atas.

(menggunakan __dict__ telah dilakukan dalam beberapa jawaban, tetapi mereka semua tidak perlu mendefinisikan metode bukannya menggunakannya secara langsung. Hanya komentar menyarankan untuk menggunakan var).

Komentar (0)
class someclass:
        x=1
        y=2
        z=3
        def __init__(self):
           self.current_idx = 0
           self.items = ["x","y","z"]
        def next(self):
            if self.current_idx < len(self.items):
                self.current_idx += 1
                k = self.items[self.current_idx-1]
                return (k,getattr(self,k))
            else:
                raise StopIteration
        def __iter__(self):
           return self

kemudian menyebutnya sebagai iterable

s=someclass()
for k,v in s:
    print k,"=",v
Komentar (1)

Jawaban yang benar untuk ini adalah bahwa anda tidak't. Jika anda ingin hal-hal baik hanya menggunakan dict, atau anda'll harus secara eksplisit menambahkan atribut untuk beberapa wadah. Anda dapat mengotomatisasi bahwa dengan belajar tentang dekorator.

Secara khusus, dengan cara, cara pemesanan1 dalam contoh anda adalah hanya sebagai baik suatu atribut.

Komentar (4)

Untuk python 3.6

class SomeClass:

    def attr_list(self, should_print=False):

        items = self.__dict__.items()
        if should_print:
            [print(f"attribute: {k}    value: {v}") for k, v in items]

        return items
Komentar (1)

Untuk python 3.6

class SomeClass:

    def attr_list1(self, should_print=False):

        for k in self.__dict__.keys():
            v = self.__dict__.__getitem__(k)
            if should_print:
                print(f"attr: {k}    value: {v}")

    def attr_list(self, should_print=False):

        b = [(k, v) for k, v in self.__dict__.items()]
        if should_print:
            [print(f"attr: {a[0]}    value: {a[1]}") for a in b]
        return b
Komentar (3)