Söz konusu sorun için, kullanmanın birkaç alternatifi olduğunu belirtmek gerekir eval
:
En basit, belirtildiği gibi kullanıyor setattr
:
def __init__(self):
for name in attsToStore:
setattr(self, name, None)
Daha az belirgin bir yaklaşım, nesnenin __dict__
nesnesini doğrudan güncellemektir . Tüm yapmak istediğiniz nitelikleri başlatmaksa, None
bu yukarıdakilerden daha az basittir. Ancak şunu düşünün:
def __init__(self, **kwargs):
for name in self.attsToStore:
self.__dict__[name] = kwargs.get(name, None)
Bu, yapıcıya anahtar kelime bağımsız değişkenleri iletmenize olanak tanır, örneğin:
s = Song(name='History', artist='The Verve')
Ayrıca locals()
daha açık bir şekilde kullanmanıza izin verir , örneğin:
s = Song(**locals())
... ve None
adları gerçekten bulunan özelliklere gerçekten atamak istiyorsanız locals()
:
s = Song(**dict([(k, None) for k in locals().keys()]))
Bir nesneye nitelikler listesi için varsayılan değerler sağlamanın başka bir yaklaşımı da sınıfın __getattr__
yöntemini tanımlamaktır :
def __getattr__(self, name):
if name in self.attsToStore:
return None
raise NameError, name
Bu yöntem, adlandırılan öznitelik normal şekilde bulunmadığında çağrılır. Bu yaklaşım, yalnızca yapıcıdaki öznitelikleri ayarlamaktan veya güncellemekten daha az basittir __dict__
, ancak sınıfın bellek kullanımını oldukça önemli ölçüde azaltabilen özniteliği olmadıkça aslında özniteliği oluşturmamaktan yararlanır.
Tüm bunların amacı: Genel olarak, kaçınmak için birçok neden vardır eval
- kontrol etmediğiniz kod yürütmenin güvenlik sorunu, hata ayıklayamadığınız pratik kod sorunu, vb. Ama daha da önemli bir neden genel olarak, onu kullanmanıza gerek yoktur. Python, iç mekanizmalarının çoğunu programcıya maruz bırakır ve nadiren gerçekten kod yazan bir kod yazmanız gerekir.
exec/eval
ve hala bilmiyordunsetattr
?