Python syntax in Lisp and Scheme
Bengt Richter
bokr at oz.net
Sun Oct 5 04:27:39 EDT 2003
On Sat, 04 Oct 2003 19:48:54 GMT, Alex Martelli <aleax at aleax.it> wrote:
>Bengt Richter wrote:
> ...
>> I like the Bunch class, but the name suggests vegetables to me ;-)
>
>Well, I _like_ vegetables...
>
>> BTW, care to comment on a couple of close variants of Bunch with
>> per-object class dicts? ...
>>
>> def mkNSC(**kwds): return type('NSC', (), kwds)()
>
>Very nice (apart from the yecchy name;-).
>
>> or, stretching the one line a bit to use the instance dict,
^^^^^^^^^^^^^^^^^^^^^^^^
>>
>> def mkNSO(**kwds): o=type('NSO', (), {})(); o.__dict__.update(kwds);
>> return o
>
>I don't see the advantage of explicity using an empty dict and then
>updating it with kwds, vs using kwds directly.
^^-- not the same dict, as you've probably thought of by now, but
glad to see I'm not the only one who misread that ;-)
I.e., as you know, the contents of the dict passed to type is used to update the fresh class dict.
It's not the same mutable dict object, (I had to check)
>>> d={'foo':'to check id'}
>>> o = type('Using_d',(),d)()
>>> d['y']='a y value'
>>> o.__class__.__dict__.keys()
['__dict__', '__module__', 'foo', '__weakref__', '__doc__']
(If d were serving as class dict, IWT y would have shown up in the keys).
and also the instance dict is only a glimmer in the trailing ()'s eye
at the point the kwd dict is being passed to type ;-)
>>> def mkNSC(**kwds): return type('NSC', (), kwds)()
...
>>> def mkNSO(**kwds): o=type('NSO', (), {})(); o.__dict__.update(kwds); return o
...
>>> class Bunch(object):
... def __init__(self, **kw): self.__dict__.update(kw)
...
>>> for inst in [mk(x=mk.__name__+'_x_value') for mk in (mkNSC, mkNSO, Bunch)]:
... cls=inst.__class__; classname = cls.__name__
... inst.y = 'added %s instance attribute y'% classname
... print '%6s: instance dict: %r' %(classname, inst.__dict__)
... print '%6s class dict keys: %r' %('', cls.__dict__.keys())
... print '%6s instance attr x: %r' %( '', inst.x)
... print '%6s instance attr y: %r' %( '', inst.y)
... print '%6s class var x : %r' %( '', cls.__dict__.get('x','<x not there>'))
... print
...
NSC: instance dict: {'y': 'added NSC instance attribute y'}
class dict keys: ['__dict__', 'x', '__module__', '__weakref__', '__doc__']
instance attr x: 'mkNSC_x_value'
instance attr y: 'added NSC instance attribute y'
class var x : 'mkNSC_x_value'
NSO: instance dict: {'y': 'added NSO instance attribute y', 'x': 'mkNSO_x_value'}
class dict keys: ['__dict__', '__module__', '__weakref__', '__doc__']
instance attr x: 'mkNSO_x_value'
instance attr y: 'added NSO instance attribute y'
class var x : '<x not there>'
Bunch: instance dict: {'y': 'added Bunch instance attribute y', 'x': 'Bunch_x_value'}
class dict keys: ['__dict__', '__module__', '__weakref__', '__doc__', '__init__']
instance attr x: 'Bunch_x_value'
instance attr y: 'added Bunch instance attribute y'
class var x : '<x not there>'
Note where x and y went. So NSC is nice and compact, but subtly different. E.g.,
>>> nsc = mkNSC(x='really class var')
>>> nsc.x
'really class var'
>>> del nsc.x
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'NSC' object attribute 'x' is read-only
(Is that's a new message with 2.3?)
>>> del nsc.__class__.x
>>> nsc.x
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'NSC' object has no attribute 'x'
NS was for Name Space, and C vs O was for Class vs obj dict initialization ;-)
Regards,
Bengt Richter
More information about the Python-list
mailing list