perulangan atas semua variabel anggota kelas dengan python

91

Bagaimana Anda mendapatkan daftar semua variabel dalam kelas yang dapat diulang? Jenis seperti penduduk setempat (), tetapi untuk kelas

class Example(object):
    bool143 = True
    bool2 = True
    blah = False
    foo = True
    foobar2000 = False

    def as_list(self)
       ret = []
       for field in XXX:
           if getattr(self, field):
               ret.append(field)
       return ",".join(ret)

ini harus kembali

>>> e = Example()
>>> e.as_list()
bool143, bool2, foo
pendeta
sumber
Mengapa tidak bisa digunakan for field in [ self.bool143, self.bool2, self.blah, self.foo, self.foobar2000 ]? Bagaimana bisa terjadi bahwa Anda tidak mengetahui variabel instan kelas?
S. Lott
4
S. Lott: lagipula itulah yang akhirnya saya lakukan. Dalam kode asli saya, saya memiliki 40 variabel, dan saya pikir akan lebih baik dan lebih KERING jika tidak perlu membuat daftar iterasi secara manual.
Imamc
3
Kemungkinan duplikat Iterasi atas atribut objek dengan python
Trevor Boyd Smith

Jawaban:

152
dir(obj)

memberi Anda semua atribut objek. Anda perlu menyaring anggota dari metode, dll sendiri:

class Example(object):
    bool143 = True
    bool2 = True
    blah = False
    foo = True
    foobar2000 = False

example = Example()
members = [attr for attr in dir(example) if not callable(getattr(example, attr)) and not attr.startswith("__")]
print members   

Akan memberimu:

['blah', 'bool143', 'bool2', 'foo', 'foobar2000']
truppo
sumber
9
mengapa membuat instance objek: dir (Example ()) alih-alih hanya tipe kelas dir (Contoh)
Erdal
8
dan bagaimana Anda mendapatkan nilainya?
knutole
7
@knutole: getattr (object, attr)
opello
8
Bagaimana cara callable(attr)kerjanya? Bukankah attrsebuah string?
cubuspl42
6
Anda seharusnya menggunakan vars(Example).items()atau vars(instance.__class__).items()bukan dir()jika Anda ingin memeriksa jika callable atau tidak karena dir hanya akan kembali ' strings sebagai nama ..
RRW
118

Jika Anda hanya menginginkan variabel (tanpa fungsi) gunakan:

vars(your_object)
Nimo
sumber
5
Anda masih perlu memfilter vars tetapi ini adalah jawaban yang benar
gaborous
3
benar-benar seperti pendekatan ini akan menggunakannya untuk mencari tahu apa yang harus diserialkan sebelum mengirim status melalui jaringan misalnya ...
Thom
7
varstidak tidak termasuk variabel kelas, hanya variabel instan.
DilithiumMatrix
2
@DilithiumMatrix Anda perlu menggunakan vars (THECLASSITSELF) pada kelas itu sendiri untuk mendapatkan variabel kelas. Cek jawaban saya di bawah ini.
AmirHossein
2
Menggunakan metode ini untuk secara khusus menjawab pertanyaan OP: members = list(vars(example).keys())karena (setidaknya dalam python3) varsmengembalikan nama dictpemetaan dari variabel anggota ke nilainya.
Michael Hall
28

@truppo: jawaban Anda hampir benar, tetapi callable akan selalu mengembalikan false karena Anda baru saja memasukkan string. Anda membutuhkan sesuatu seperti berikut:

[attr for attr in dir(obj()) if not callable(getattr(obj(),attr)) and not attr.startswith("__")]

yang akan memfilter fungsi

pengguna235925
sumber
6
>>> a = Example()
>>> dir(a)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__',
'__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', 'bool143', 'bool2', 'blah',
'foo', 'foobar2000', 'as_list']

—Seperti yang Anda lihat, itu memberi Anda semua atribut, jadi Anda harus menyaring sedikit. Tapi pada dasarnya, dir()itulah yang Anda cari.

balpha
sumber
-1
row2dict = lambda r: {c.name: str(getattr(r, c.name)) for c in r.__table__.columns} if r else {}

Gunakan ini.

pengguna1825586
sumber
Menyesatkan. Tidak ada atribut ' tabel ' di kelas secara default.
ben26941
-2
    class Employee:
    '''
    This class creates class employee with three attributes 
    and one function or method
    '''

    def __init__(self, first, last, salary):
        self.first = first
        self.last = last
        self.salary = salary

    def fullname(self):
        fullname=self.first + ' ' + self.last
        return fullname

emp1 = Employee('Abhijeet', 'Pandey', 20000)
emp2 = Employee('John', 'Smith', 50000)

print('To get attributes of an instance', set(dir(emp1))-set(dir(Employee))) # you can now loop over
Abhijeet Pandey
sumber
-3

Cara mudah untuk melakukannya adalah dengan menyimpan semua instance kelas di file list.

a = Example()
b = Example()
all_examples = [ a, b ]

Objek tidak muncul secara spontan. Beberapa bagian dari program Anda membuatnya karena suatu alasan. Penciptaan dilakukan karena suatu alasan. Mengumpulkan mereka dalam daftar juga bisa dilakukan karena suatu alasan.

Jika Anda menggunakan pabrik, Anda bisa melakukan ini.

class ExampleFactory( object ):
    def __init__( self ):
        self.all_examples= []
    def __call__( self, *args, **kw ):
        e = Example( *args, **kw )
        self.all_examples.append( e )
        return e
    def all( self ):
        return all_examples

makeExample= ExampleFactory()
a = makeExample()
b = makeExample()
for i in makeExample.all():
    print i
S. Lott
sumber
Saya suka idenya (saya mungkin benar-benar menggunakannya dalam proyek saat ini). Ini bukan jawaban untuk pertanyaan: OP ingin membuat daftar atribut, bukan contoh itu sendiri.
balpha
@balpha: Ups. Tidak membaca pertanyaannya. 90% dari waktu, ini adalah duplikat dari "bagaimana cara menemukan semua instance kelas." Pertanyaan sebenarnya (setelah Anda menunjukkannya) tidaklah masuk akal. Anda tahu variabel instan, buat saja daftar.
S. Lott