python'da bir sınıfın tüm üye değişkenleri üzerinde döngü yapmak


91

Yinelenebilir bir sınıftaki tüm değişkenlerin bir listesini nasıl elde edersiniz? Yerliler gibi (), ancak bir sınıf için

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)

bu geri dönmeli

>>> e = Example()
>>> e.as_list()
bool143, bool2, foo

Neden kullanamıyorsun for field in [ self.bool143, self.bool2, self.blah, self.foo, self.foobar2000 ]? Nasıl oluyor da sınıfın örnek değişkenlerini bilmiyorsunuz?
S.Lott

4
S.Lott: Zaten yaptığım şey buydu. Gerçek kodumda, 40 kadar değişken var ve yineleme listesini manuel olarak yapmak zorunda kalmamanın daha iyi ve daha KURU olacağını düşündüm.
priestc

Yanıtlar:


152
dir(obj)

size nesnenin tüm niteliklerini verir. Üyeleri yöntemlerden vb. Kendiniz filtrelemeniz gerekir:

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   

Sana vereceğim:

['blah', 'bool143', 'bool2', 'foo', 'foobar2000']

9
neden sadece bir sınıf türü yerine dir (Örnek ()) örneğini oluşturalım dir (Örnek)
Erdal

8
ve değerleri nasıl elde edersiniz?
knutole

7
@knutole: getattr (nesne, attr)
opello

8
Nasıl callable(attr)çalışır? attrBir dizi değil mi?
cubuspl42

6
Eğer kullanılmış olmalıdır vars(Example).items()veya vars(instance.__class__).items()yerine dir()kontrol etmek istediğiniz eğer onun çağrılabilir veya sadece 'dönecektir dir çünkü stringadları gibi s ..
RRW

118

Yalnızca değişkenleri istiyorsanız (işlevsiz) şunu kullanın:

vars(your_object)

5
Yine de değişkenleri filtrelemeniz gerekiyor ama bu doğru cevap
titiz

3
gerçekten bu yaklaşım, örneğin ağ üzerinden durumları göndermeden önce neleri serileştireceğini bulmak için kullanacak gibi ...
Thom

7
varsyok değil sınıf değişkenleri, sadece örnek değişkenlerini içerir.
DilithiumMatrix

2
@DilithiumMatrix, sınıf değişkenlerini almak için sınıfın kendisinde vars (THECLASSITSELF) kullanmanız gerekir. Aşağıdaki cevabımı kontrol edin.
AmirHossein

2
OP'nin sorusuna özel olarak cevap vermek için bu yöntemi kullanmak: members = list(vars(example).keys())as (en azından python3'te) üye değişkenin adını değerine eşleyen bir varsdöndürür dict.
Michael Hall

28

@truppo: cevabınız neredeyse doğrudur, ancak çağrılabilir her zaman yanlış döndürür, çünkü sadece bir dizge geçtiğiniz için. Aşağıdakine benzer bir şeye ihtiyacınız var:

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

hangi fonksiyonları filtreleyecek


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

—Gördüğünüz gibi, bu size tüm nitelikleri verir , bu yüzden biraz filtrelemeniz gerekecek. Ama temelde dir()aradığınız şey bu.


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

Bunu kullan.


Yanıltıcı. Sınıflarda varsayılan olarak " tablo " özelliği yoktur .
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

-3

Bunu yapmanın kolay yolu, sınıfın tüm örneklerini bir list.

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

Nesneler kendiliğinden ortaya çıkmaz. Programınızın bir kısmı onları bir nedenle yarattı. Yaratılışın bir nedeni var. Bunları bir listede toplamak da bir sebeple yapılabilir.

Bir fabrika kullanıyorsanız, bunu yapabilirsiniz.

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

Bu fikri beğendim (bunu mevcut bir projede gerçekten kullanabilirim). Yine de sorunun cevabı değil: OP, örneklerin kendisini değil öznitelikleri listelemek istiyor.
balpha

@balpha: Ooops. Soruyu okumadım. % 90 oranında "bir sınıfın tüm örneklerini nasıl bulurum" ifadesinin kopyasıdır. Asıl soru (şimdi işaret ettiğinize göre) mantıklı değil. Örnek değişkenlerini biliyorsunuz, sadece bir liste yapın.
S.Lott
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.