On Fri, 15 May 2015 06:59 pm, Marko Rauhamaa wrote: > However, in some respects, Python might be going overboard with its > dynamism; are all those dunder methods really needed? Must "false" be > defined so broadly? Must a method lookup necessarily involve object > creation?
Yes, what do you mean, and no. (1) Yes, the dunder methods are necessary to support operator overloading and various other protocols. The existence of dunder methods doesn't have any runtime costs except for that related to memory usage. Fortunately, the dunder methods only exist on the class itself, not each and every instance. (2) What do you mean by false being defined so broadly? The singleton instance False is not defined broadly at all. It is a built-in constant, and there's only one of it. In Python 3, "False" is even a keyword, so you cannot redefine the name. (It's not a keyword in Python 2 because of historical reasons.) Perhaps you are talking about falsey (false-like) instances, e.g. if []: ... else: ... will run the else block. That's quite broad, in a sense, but it has no real runtime cost over and above a more Pascal-ish language would force you to have: if len([]) == 0: ... else: ... Because True and False are singletons, the overhead of testing something in a boolean context is no greater than the cost of testing the same condition by hand. That is, it makes no difference whether you manually compare the list's length to zero, or let its __nonzero__ or __bool__ method do the same. (If anything, using an implicit boolean test will be faster than an explicit manual test, because it doesn't have to call the len() global.) (3) Method lookups don't *necessarily* have to involve object creation. The only semantics which Python requires (so far as I understand it) are: - Taking a reference to an unbound method: ref = str.upper may return the function object itself, which clearly already exists. - Taking a reference to a bound method: ref = "some string".upper must return a method object, but it doesn't have to be recreated from scratch each and every time. It could cache it once, then always return that. That, I believe, is an implementation detail. - Calling a method may bypass creating a method, and just use the function object directly, provided Python knows that the descriptor has no side-effects. For example, since FunctionType.__get__ has no side-effects, a Python interpreter could special-case function objects and avoid calling the descriptor protocol when it knows that the method is just going to be called immediately. But... having said all that... how do you know that these issues are bottlenecks that eliminating them would speed up the code by any significant amount? -- Steven -- https://mail.python.org/mailman/listinfo/python-list