__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
Burada çalışan iki temel mesele var:
__xxx__
yöntemler sadece sınıfa baktı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
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.
Getattr() tam olarak ne ve nasıl kulla...