SORU
15 Mart 2010, PAZARTESİ


__modülü__ getattr

Nasıl bir sınıf üzerinde __getattr__ eşdeğer, bir modül üzerine uygulayabilirsiniz?

Örnek

Ne zaman bir arama fonksiyonu var olmayan bir modülün statik olarak tanımlanan öznitelikleri, keşke bir örnek oluşturmak için bir sınıf olarak bu modül ve çağırma yöntemi ile aynı adı başarısız özniteliği ' Arama modülü.

class A(object):
    def salutation(self, accusative):
        print "hello", accusative

# note this function is intentionally on the module, and not the class above
def __getattr__(mod, name):
    return getattr(A(), name)

if __name__ == "__main__":
    # i hope here to have my __getattr__ function above invoked, since
    # salutation does not exist in the current namespace
    salutation("world")

Hangi verir:

matt@stanley:~/Desktop$ python getattrmod.py 
Traceback (most recent call last):
  File "getattrmod.py", line 9, in <module>
    salutation("world")
NameError: name 'salutation' is not defined

CEVAP
5 EKİM 2011, ÇARŞAMBA


Burada çalışan iki temel mesele var:

  1. __xxx__ yöntemler sadece sınıfa baktı
  2. TypeError: can't set attributes of built-in/extension type 'module'

(1) anlamına gelir, herhangi bir çözüm de hangi modül muayene ediliyordu takip etmek için, başka türlü olurduhermodülü daha sonra örnek, ikame davranış olurdu; ve (2) anlamına gelir (1) bile mümkün... en azından doğrudan değil.

Neyse ki, sys.modüller değil seçici hakkında ne işte öyle bir kapsayıcı çalışacaktır, ama sadece erişim modülü (yani import somemodule; somemodule.salutation('world'); aynı modül erişim oldukça fazla olması yank yöntemleri ikame sınıf ve onları eklemek için globals() eiher ile özel bir sınıf yöntemi (ben gibi kullanarak .export()) ya da bir genel fonksiyon (gibi olanlar zaten listede cevap). Akılda tutulması gereken bir şey: kapsayıcı yeni bir örneğini her zaman yaratıyor ve bütünsel çözüm değil, kurnazca farklı davranış. Oh, ve her ikisi de aynı anda bir ya da kullanmak zorunda değilsin.


Güncelleme

Guido van Rossum:

Aslında ara sıra kullanılan ve önerilen hack var: modül istenen işlevi, ve sonra bir sınıf tanımlayabilirsiniz sonunda, sys kendini değiştir.bu sınıfın bir örneği ile modülleri (ya da eğer ısrar ediyorsan, ama genellikle daha az yararlı olan Sınıf, ile). E. g.:

# module foo.py

import sys

class Foo:
    def funct1(self, <args>): <code>
    def funct2(self, <args>): <code>

sys.modules[__name__] = Foo()

Bu ithal makine aktif olarak bu etkinleştirme çalışıyor çünkü son adım dışında gerçek modül çeker gibi hack ve sys.modüller, yüklemeden sonra. (Bu bir tesadüf değil. Hack oldu ve bunu destekleyecek kadar hoşlandığımıza karar verdik uzun zaman önce önerilen makine alın.)

Bu yüzden kurulmuş şekilde gerçekleştirmek istediğin oluşturun tek bir sınıf modülü, ve son olarak da hareket modülünü değiştirin sys.modules[__name__] örneği ile sınıf -- ve şimdi sen-ebilmek oyun ile __getattr__/__setattr__/__getattribute__ gerektiği gibi.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Ampisound

    Ampisound

    12 Kasım 2006
  • GavinMichaelBooth

    GavinMichael

    26 AĞUSTOS 2006
  • Kupa World

    Kupa World

    1 EYLÜL 2011

İLGİLİ SORU / CEVAPLAR