Bu kod parçası, dinamik adlar ve parametre adları ile yeni sınıflar oluşturmanıza olanak tanır. Parametre doğrulaması, __init__
bilinmeyen parametrelere izin vermez, tür gibi başka doğrulamalara ihtiyacınız varsa veya bunların zorunlu olduğunu, sadece mantığı buraya ekleyin:
class BaseClass(object):
def __init__(self, classtype):
self._type = classtype
def ClassFactory(name, argnames, BaseClass=BaseClass):
def __init__(self, **kwargs):
for key, value in kwargs.items():
if key not in argnames:
raise TypeError("Argument %s not valid for %s"
% (key, self.__class__.__name__))
setattr(self, key, value)
BaseClass.__init__(self, name[:-len("Class")])
newclass = type(name, (BaseClass,),{"__init__": __init__})
return newclass
Ve bu şu şekilde çalışır, örneğin:
>>> SpecialClass = ClassFactory("SpecialClass", "a b c".split())
>>> s = SpecialClass(a=2)
>>> s.a
2
>>> s2 = SpecialClass(d=3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in __init__
TypeError: Argument d not valid for SpecialClass
Dinamik isimleri adlandırma kapsamına eklemeyi istediğinizi görüyorum - şimdi, bu Python'da iyi bir uygulama olarak görülmüyor - ya kodlama zamanında bilinen değişken isimleriniz ya da verileriniz var - ve çalışma zamanında öğrenilen isimler daha fazla " veriler "değişkenlerden" -
Yani, sınıflarınızı bir sözlüğe ekleyebilir ve oradan kullanabilirsiniz:
name = "SpecialClass"
classes = {}
classes[name] = ClassFactory(name, params)
instance = classes[name](...)
Ve tasarımınız kesinlikle adların kapsamına ihtiyaç duyuyorsa, sadece aynısını yapın, ancak globals()
rastgele bir sözlük yerine çağrı tarafından döndürülen sözlüğü kullanın :
name = "SpecialClass"
globals()[name] = ClassFactory(name, params)
instance = SpecialClass(...)
(Sınıf fabrikası işlevinin adı dinamik olarak arayanın genel kapsamına eklemesi gerçekten mümkün olabilir - ancak bu daha da kötü bir uygulamadır ve Python uygulamalarıyla uyumlu değildir. Bunu yapmanın yolu, arayanın yürütme çerçevesi, sys._getframe (1) aracılığıyla ve sınıf adını çerçevenin genel sözlüğünde f_globals
özniteliğinde ayarlama).
update, tl; dr: Bu cevap popüler hale geldi, hala soru gövdesine özgü.
Python'da "bir temel sınıftan dinamik olarak türetilmiş sınıfların nasıl oluşturulacağına " ilişkin genel yanıt
type
, yeni sınıf adını, temel sınıf (lar) ı içeren bir demet ve yeni sınıf için gövdeyi iletmeye yönelik basit bir çağrıdır __dict__
- buna benzer:
>>> new_class = type("NewClassName", (BaseClass,), {"new_method": lambda self: ...})
update Buna
ihtiyaç duyan herkes dereotu projesini de kontrol etmelidir - tıpkı sıradan nesnelere turşunun yaptığı gibi sınıfları turşu yapıp çözebildiğini iddia ediyor ve bazı testlerimde bunu yaşamıştı.
a
, her zaman olacakMyClass
veTestClass
asla almayacaka
mı? Neden 3 bağımsız değişkenin tümünü açıklayıp hepsiniBaseClass.__init__()
varsayılan olarak belirtmiyorsunuzNone
?def __init__(self, a=None, b=None, C=None)
?