2010-10-06 25 views
6

Python metaclass'larında bazı eğitici yazıları okudum. Daha önce hiç kullanmadım, ama göreceli olarak basit bir şeye ihtiyacım var ve tüm dersler çok daha karmaşık kullanım durumlarına yönelik görünüyor. Temel olarak önceden belirlenmiş bir gövdeye sahip bir şablon sınıfı oluşturmak istiyorum, ancak temel sınıfını bir parametre olarak alıyor. kesinlikle metaclasses ile yapılabilir rağmenParametrelere Metaclass Miras

template<class T> 
    class Foo : T { 
     void fun() {} 
    } 

cevap

9

, istediğini yapabilirsin: C++/D şablonlardan fikrim var olduğundan, burada ++ kod ben C gibi görünecektir yazmak istiyorum bir örnek onlarsız, çünkü Python sınıflarında kendilerini nesneler. Şaşırtıcı bir şekilde, aslında C++ kodunun neredeyse bire bir çevirisi olmaktan başka bir şey gerekli değildir.

Foo_Base1 base classes: (<class __main__.Base1 at 0x00A79C38>,) 
Foo_Base2 base classes: (<class __main__.Base2 at 0x00A79DC0>,) 
Foo_Base1.fun() 
Base1.bar() 
Foo_Base2.fun() 
Base2.bar() 

(unimaginatively adlandırılmış) template() işlevinde kod şudur: bu nedenle nispeten karmaşık olmayan olmasının yanı sıra, aynı zamanda 2 & 3.

def template(class_T): 
    """Factory function to create subclasses of class_T.""" 

    class Foo(class_T): 
     def fun(self): 
      print('%s.fun()' % self.__class__.__name__) 

    Foo.__name__ += '_' + class_T.__name__ # rename the subclass to reflect its heritage 
    return Foo 

class Base1: 
    def bar(self): 
     print('Base1.bar()') 

class Base2: 
    def bar(self): 
     print('Base2.bar()') 

Foo_Base1 = template(Base1) 
print('Foo_Base1 base classes: {}'.format(Foo_Base1.__bases__)) 

Foo_Base2 = template(Base2) 
print('Foo_Base2 base classes: {}'.format(Foo_Base2.__bases__)) 

subclass1 = Foo_Base1() 
subclass1.fun() 
subclass1.bar() 
subclass2 = Foo_Base2() 
subclass2.fun() 
subclass2.bar() 

Çıktı Python hem de değişiklik yapılmaksızın çalışacağız Genel olarak class factory veya Fabrika modelinin fabrika modelinin bir uygulaması olarak adlandırılır. Bu nedenle, What exactly is a Class Factory? bilgi için my answer bulabilirsiniz.

Düzenleme: hep imal sınıf aynı ada sahip olmadığını ayıklarken potansiyel karışıklık hakkında (a şimdi silinmiş açıklamada) @aaronasterling 'ın anlayış esinlenerek döndürülen-Her alt sınıf için farklı sınıf adları oluşturmak için Eklendi kodu .

+0

Müthiş, ben metaclasses kadar basit bir şey tarafından olduğu düşünülen sanırım. Bu çözüm, Python'da birinci sınıf nesneler olduğundan ve çalışma zamanında sınıflar oluşturulabildiğinden, arka görüşte tonlarca anlam ifade eder. Sanırım dinamik dil düşüncesiyle yeterince rahat edemedim, ama yine de kendi başıma gelmeyi düşünüyorum. – dsimcha

+0

Şablonlar * C++ dilinde güçlü bir şekilde yazılmış bir dildir. Sınıfların da belirttiğiniz nesneler olduğu Python gibi zayıf yazılmış bir yazıda, genellikle oraya gitmek gerekli değildir - ama yaptığınız zaman, şablon argümanlarıyla sınırlı kalmazsınız ve bazı şaşırtıcı şeyler yapabilirsiniz. – martineau

+6

** Python güçlü bir şekilde yazılmıştır **, Javascript gibi zayıf yazılmış bir dilde yaptığınız gibi Python'da bir dize ve tamsayı ekleyemezsiniz. Bu arada, ** Python da dinamik olarak yazılmıştır **. –

0

Python'da bu şablonlar olmadığı için anlamsızdır. C++ 'daki parametrelenmiş şablonlar hakkındaki anlayışım (ki bu, onlara baktığımdan beri uzun yıllar oldu, çünkü oldukça belirsiz), bir sınıf fabrikası gibi davranıyor ve ek yöntemleri olan her hangi bir sınıfın alt sınıfını oluşturabilir veya özellikler eklendi.

Python size bir sınıf alır ve zamanında yeni bir sınıf döndüren bir fabrika fonksiyonu ile yapabilirsiniz:

In [1]: def subclassFactory(cls): 
    ...:  class Foo(cls): 
    ...:   def fun(self): 
    ...:    return "this is fun" 
    ...:  return Foo 
    ...: 

In [2]: class A(object): 
    ...:  pass 
    ...: 

In [5]: C = subclassFactory(A) 

In [6]: C 
Out[6]: <class '__main__.Foo'> 
In [7]: c = C() 
In [9]: c.fun() 
Out[9]: 'this is fun' 
In [10]: isinstance(c, A) 
Out[10]: True 
İlgili konular