On Monday, February 2, 2015 at 9:34:53 AM UTC+5:30, Rustom Mody wrote: > On Monday, February 2, 2015 at 9:22:51 AM UTC+5:30, Rustom Mody wrote: > > On Sunday, February 1, 2015 at 9:51:11 PM UTC+5:30, Steven D'Aprano wrote: > > > Rustom Mody wrote: > > > > > > > The other day I was taking a class in which I was showing > > > > - introspection for discovering -- help, type, dir etc at the repl > > > > - mapping of surface syntax to internals eg. a + b ←→ a.__add__(b) > > > > > > > > And a student asked me the diff between > > > > dir([]) > > > > and > > > > [].__dir__() > > > > > > > > I didnt know what to say... > > > > > > Surely the right answer would have been "I don't know, let's check the > > > interactive interpreter first, and the docs second." > > > > > > Checking the REPL first would have revealed that [].__dir__ raises > > > AttributeError. In other words, lists don't have a __dir__ method. > > > > ?? > > > > $ python3 > > Python 3.4.2 (default, Oct 8 2014, 13:08:17) > > [GCC 4.9.1] on linux > > Type "help", "copyright", "credits" or "license" for more information. > > >>> [].__dir__ > > <built-in method __dir__ of list object at 0x7f5dd2209f48> > > >>> dir([]) > > ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', > > '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', > > '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', > > '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', > > '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', > > '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', > > 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', > > 'remove', 'reverse', 'sort'] > > >>> [].__dir__() > > ['__rmul__', '__str__', '__gt__', 'remove', '__class__', '__getitem__', > > '__format__', '__ne__', '__sizeof__', '__contains__', '__reduce__', > > '__add__', 'sort', 'count', 'extend', '__mul__', '__imul__', > > '__reduce_ex__', '__setitem__', '__doc__', '__ge__', 'copy', '__init__', > > '__iadd__', '__hash__', '__delitem__', 'insert', '__iter__', '__repr__', > > '__le__', '__setattr__', 'reverse', '__new__', '__eq__', '__len__', > > 'index', '__lt__', 'clear', '__subclasshook__', 'append', '__dir__', > > '__reversed__', '__getattribute__', 'pop', '__delattr__'] > > >>> > > > > What you are describing seems to be true for python2 though > > And since they *looked* different I believed they were different. > > Evidently not… > > >>> s1= set([].__dir__()) > >>> s2=set(dir([])) > >>> s1 > {'__rmul__', '__str__', '__class__', '__ne__', '__repr__', '__format__', > '__sizeof__', '__contains__', '__add__', 'sort', 'count', 'extend', 'remove', > '__mul__', '__reduce__', '__imul__', '__reduce_ex__', '__setitem__', > 'insert', '__doc__', '__ge__', 'index', 'copy', '__subclasshook__', > '__getitem__', '__init__', '__iadd__', '__hash__', '__delitem__', '__iter__', > '__le__', '__setattr__', 'reverse', '__new__', '__eq__', '__len__', '__lt__', > 'clear', '__gt__', 'append', '__dir__', '__reversed__', '__getattribute__', > 'pop', '__delattr__'} > >>> s2 > {'__rmul__', '__str__', '__class__', '__ne__', '__repr__', '__format__', > '__sizeof__', '__contains__', '__add__', 'sort', 'count', 'extend', > '__mul__', 'remove', '__imul__', '__reduce__', '__reduce_ex__', > '__setitem__', 'insert', '__doc__', '__ge__', '__subclasshook__', 'copy', > 'index', '__getitem__', '__iadd__', '__init__', '__hash__', '__delitem__', > '__iter__', '__le__', '__setattr__', 'reverse', '__new__', '__eq__', > '__len__', '__lt__', 'clear', '__gt__', 'append', '__dir__', '__reversed__', > '__getattribute__', 'pop', '__delattr__'} > >>> len(s1) > 45 > >>> len(s2) > 45 > >>> s1 - s2 > set() > >>> s2 - s1 > set()
Well I continue to be fooled >>> d1 = {k:getattr([],k) for k in [].__dir__()} >>> d2 = {k:getattr([],k) for k in dir([])} >>> d1 == d2 False >>> len(d1) 45 >>> len(d2) 45 >>> d1.keys() dict_keys(['__rmul__', '__str__', '__gt__', '__mul__', '__class__', '__ne__', '__format__', '__sizeof__', '__contains__', '__imul__', '__add__', 'sort', 'count', 'extend', 'remove', '__init__', 'insert', '__setitem__', 'index', '__subclasshook__', 'copy', '__getitem__', '__iadd__', '__hash__', '__delitem__', '__reduce_ex__', '__iter__', '__repr__', '__le__', '__setattr__', 'reverse', '__new__', '__eq__', '__len__', '__doc__', '__lt__', 'clear', '__ge__', 'append', '__dir__', '__reversed__', '__getattribute__', 'pop', '__delattr__', '__reduce__']) >>> d1.keys() == d2.keys() True -- https://mail.python.org/mailman/listinfo/python-list