Rasgele öznitelik atamasını desteklemek için, bir nesnenin bir __dict__
: nesneye ilişkin bir dikteye ihtiyacı vardır , burada rasgele öznitelikler depolanabilir. Aksi takdirde, yeni nitelikler koyacak yer yoktur .
Bir örneği object
yok değil taşımak bir __dict__
- bu yaptıysam, korkunç dairesel bağımlılık sorunu (öncesinden bu yana dict
, başka pek çok şey gibi, devralır object
, bu altına sokacak ;-) her bir yükü anlamına gelecektir ki, bir dict ile Python nesne ait birçok şu anda sahip veya dicti ihtiyacı yoktur o nesnenin başına bayt (aslında, yok tüm nesneler keyfi atanabilir nitelikler varsa veya bir dicti gerekmez).
Örneğin, mükemmel pympler
projeyi kullanarak ( buradan svn aracılığıyla alabilirsiniz ), bazı ölçümler yapabiliriz ...:
>>> from pympler import asizeof
>>> asizeof.asizeof({})
144
>>> asizeof.asizeof(23)
16
Her int
birinin yalnızca 16 yerine 144 baytı almasını istemezsiniz , değil mi? -)
Şimdi, bir sınıf oluşturduğunuzda (her neyse), işler değişir ...:
>>> class dint(int): pass
...
>>> asizeof.asizeof(dint(23))
184
... __dict__
olduğu şimdi eklenen (artı, biraz daha havai) - Bir nedenle dint
örneği keyfi nitelikleri olabilir, ancak bu esneklik için oldukça uzay maliyetini ödemek.
Peki ya int
sadece bir ekstra özelliğe sahip olmak isteseydin foobar
...? Bu nadir bir ihtiyaç, ancak Python bu amaç için özel bir mekanizma sunuyor ...
>>> class fint(int):
... __slots__ = 'foobar',
... def __init__(self, x): self.foobar=x+100
...
>>> asizeof.asizeof(fint(23))
80
... değil oldukça bir şekilde minik olarak int
, çekerim! (veya hatta iki int
s, biri self
ve biri self.foobar
- ikincisi yeniden atanabilir), ama kesinlikle a'dan çok daha iyi dint
.
Sınıf sahip olduğunda __slots__
özel niteliği (dizeleri dizisi), sonra class
deyimi (daha doğrusu varsayılan metaclass, type
etmez) değil bir ile bu sınıfın her örneğini donatmak __dict__
(keyfi özelliklere sahiptir ve bu nedenle yeteneği), sadece sonlu , verilen isimlerle katı "yuvalar" (temelde her biri bir nesneye bir referans tutabilen yerler).
Kayıp esneklik karşılığında, örnek başına çok fazla bayt kazanırsınız (muhtemelen yalnızca etrafta dolaşan zilyonlarca örneğiniz varsa anlamlıdır, ancak bunun için kullanım durumları vardır).
object
Tür değişmez ve yeni nitelikler eklenemez mi? Bu en mantıklı olacak gibi görünüyor.