Nesnenin yöntem ve özniteliklerinin tam listesi nasıl alınır?


230
dir(re.compile(pattern)) 

listenin öğelerinden biri olarak desen döndürmez. Yani geri döner:

['__copy__', '__deepcopy__', 'findall', 'finditer', 'match', 'scanner', 'search', 'split', 'sub', 'subn']

El kitabına göre,

nesnenin özniteliklerinin adları, sınıfının özniteliklerinin adları ve sınıfının temel sınıflarının özyinelemeleri.

Ayrıca şunu da söylüyor

Liste tam olarak zorunlu değildir.

Tam listeyi almanın bir yolu var mı ? Her zaman dir tam bir liste döndürdüğünü varsaydı ama görünüşe göre değil ...

Ayrıca: yalnızca özellikleri listelemenin bir yolu var mı? Yoksa sadece yöntemler mi?

Düzenleme: Bu aslında python bir hata -> sözde 3.0 dalında sabit (ve belki de 2.6)


5
kullanarak dir()veya modül genellikle bunu yapmak için doğru yolu kontrol edin. reModülü örnek olarak mı kullandınız yoksa özel bir hedefe mi ulaşmak istiyorsunuz?

1
Desenin bir kez derlendiğinde veri olarak saklandığından emin misiniz? Bir patern derleme noktasının verilen paterni ayrıştırmak için gerekli sonlu durum otomatlarını üretmek olduğu izlenimi altındaydım.
Kyle Strand

@hop sınıflar tarafından yönlendirilemez mi? Örneğin, on__dir__()
ytpillai

ytpillai: doğru, ama sadece Python 3'te. Öyle olsa bile, soru, böyle bir sınıfın "genel durum" altına girip

Yanıtlar:


140

Özelliklerin tam listesi için kısa cevap: hayır. Sorun, özniteliklerin aslında getattryerleşik işlev tarafından kabul edilen argümanlar olarak tanımlanmasıdır . Kullanıcı yeniden anlayabildiğinden __getattr__, aniden her türlü özelliğe izin verdiğinden, bu listeyi oluşturmanın olası bir genel yolu yoktur. dirFonksiyon tuşları döndüren __dict__özelliğin, yani eğer tüm erişilebilir niteliklerini __getattr__yöntem reimplemented değildir.

İkinci soru için, gerçekten mantıklı değil. Aslında, yöntemler çağrılabilir niteliklerdir, başka bir şey değildir. Yine de çağrılabilir nitelikleri filtreleyebilir ve inspectmodülü kullanarak sınıf yöntemlerini, yöntemlerini veya işlevlerini belirleyebilirsiniz.


1
inpect.getmembers (re.compile (pattern)) de üye olarak desen vermez, bu yüzden muhtemelen dir dahili olarak kullanır ... Bu berbat!
Bartosz Radaczyński

Ayrıca yöntem olup olmadığını kontrol etmek için çağrılabilir kullanabilirsiniz, ama bu nokta değil ... Asıl nokta aslında halka açık olan öznitelikler listesi bile dönmek için dir güvenemiyorum ...
Bartosz Radaczyński

2
teftiş dir () kadar güvenilir olmalıdır. diğer yandan, re çok karmaşık bir modül

"Herkes tarafından görülebilir" ile neyi tanımlarsınız? "Ulaşılabilir" demek istiyorsan, verilen sebepten dolayı kaybolan bir nedendir. Aksi takdirde, 'dir' her zaman varsayılan getattr uygulamasıyla erişilebilen öznitelikler listesini döndürür.
PierreBdR

2
dir (my_class), my_class .__ dict __. keys () öğesinden farklı bir şey döndürür. birincisi ayrıca init ve doc
çıkarır

58

Bu nedenle yeni __dir__()yöntem python 2.6'ya eklendi

görmek:


Bu hatayı alıyorum: >> dir __ (pyrenderdoc) Geri izleme (en son çağrı son): <module> NameError'da "<string>" dosyası, satır 1 tanımlanmadı
Mona Jalal

__dir__ () nesne üzerinde bir yöntem değil, bir işlevdir - lütfen cevaptaki bağlantıları okuyun ve bu
Moe

Tüm özellikleri ve değerlerini yazdırmak için bir astar:pprint({k:getattr(ojb,k) for k in obj.__dir__()})
Çeknoloji

21

İşte PierreBdR ve Moe cevaplarına pratik bir ek:

  • Python için> = 2.6 ve yeni tarzı sınıfları , dir()yeterli gibi görünüyor.
  • İçin eski tarz sınıfları , en azından bir ne yapabilirim standart modül ek olarak: Destek sekmesi tamamlanması için yaptığı dir()için görünüm, __class__onun için gitmek sonra ve __bases__:

    # code borrowed from the rlcompleter module
    # tested under Python 2.6 ( sys.version = '2.6.5 (r265:79063, Apr 16 2010, 13:09:56) \n[GCC 4.4.3]' )
    
    # or: from rlcompleter import get_class_members
    def get_class_members(klass):
        ret = dir(klass)
        if hasattr(klass,'__bases__'):
            for base in klass.__bases__:
                ret = ret + get_class_members(base)
        return ret
    
    
    def uniq( seq ): 
        """ the 'set()' way ( use dict when there's no set ) """
        return list(set(seq))
    
    
    def get_object_attrs( obj ):
        # code borrowed from the rlcompleter module ( see the code for Completer::attr_matches() )
        ret = dir( obj )
        ## if "__builtins__" in ret:
        ##    ret.remove("__builtins__")
    
        if hasattr( obj, '__class__'):
            ret.append('__class__')
            ret.extend( get_class_members(obj.__class__) )
    
            ret = uniq( ret )
    
        return ret

(Test kodu ve çıktı kısalık için silinir, ancak temel olarak yeni stil nesneleri için get_object_attrs()olduğu gibi aynı sonuçlara sahip olduğumuzu dir()ve eski stil sınıfları için dir()çıktıya ana ekleme__class__ öznitelik .)


9

Sadece ek olarak:

  1. dir()olduğu en güçlü / temel bir araç. ( En çok tavsiye edilen )
  2. Çözümler dir()sadece çıktılarını ele alma yollarını sağlar .dir()

    2. seviye nitelikleri listelemek ya da istememek, elemeyi kendiniz yapmanız önemlidir, çünkü bazen iç değişkenleri önde gelen alt çizgilerle elemek isteyebilirsiniz __, ancak bazen __doc__doc-string'e ihtiyacınız olabilir .

  3. __dir__()ve dir()aynı içeriği döndürür.
  4. __dict__ve dir()farklı. __dict__eksik içerik döndürür.
  5. ÖNEMLİ : __dir__()bazen yazar tarafından herhangi bir amaç için bir işlev, değer veya tür ile yazılabilir.

    İşte bir örnek:

    \\...\\torchfun.py in traverse(self, mod, search_attributes)
    445             if prefix in traversed_mod_names:
    446                 continue
    447             names = dir(m)
    448             for name in names:
    449                 obj = getattr(m,name)

    TypeError: açıklayıcısı __dir__ait 'object'nesne bir argüman ihtiyacı

    PyTorch'un yazarı __dir__()yöntemi argüman gerektiren bir şeye değiştirdi . Bu değişiklik dir()başarısız olur.

  6. Bir nesnenin tüm niteliklerini aşmak için güvenilir bir şema istiyorsanız , her pitonik standardın üzerine yazılabileceğini ve tutamayabileceğini ve her kuralın güvenilir olmayabileceğini unutmayın.


5

Öznitelikleri eklemeye devam ettiğiniz basit özel nesneler için bu şekilde yapıyorum:

İle oluşturulmuş obj = type("Obj",(object,),{})veya basitçe:

class Obj: pass
obj = Obj()

Bazı özellikler ekleyin:

obj.name = 'gary'
obj.age = 32

ardından yalnızca özel özelliklere sahip bir sözlük elde etmek için:

{key: value for key, value in obj.__dict__.items() if not key.startswith("__")}

# {'name': 'gary', 'age': 32}

Python 3.x'teki tüm özelliklerin listesi: {key: anahtar için değer, obj .__ dict __. items () değilse key.startswith ("__")} ['_
beyaned_fields
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.