On 6 October 2017 at 13:44, ROGER GRAYDON CHRISTMAN <d...@psu.edu> wrote: > Despite the documentation, I would still be tempted to say that range is a > function. > Taking duck-typing to the meta-level, every time I use range, I use its name > followed > by a pair of parentheses enclosing one to three parameters, and I get back an > immutable sequence object. It sure looks like a function to me. > > I would similarly say that map is a function, or an iterator generator I write > myself > with yield statements is a function, both of which also return sequences. > It is not clear to me what the difference really is between my conception > and the official definition -- is it a question about whether it returns a > first-class object? > > Or more simply, what is the clear and obvious distinction that I can give to > my > non-scientific laypeople about why range isn't a function, if it looks like > one?
Technically, range (and the other examples you mentioned) is a "callable". The concept of a callable is closer to the intuitive meaning of "function" than the things Python technically calls functions. And most code accepts callables rather than functions (i.e., there's little if anything that rejects range because it's a callable not a function). Duck typing means that you can take class C: pass c = C() and replace it with class C_impl: pass def C(): return C_impl() c = C() and there's little or no difference. In the first, C is a class. In the second it's a (factory) function. You can tell the difference, via introspection. But it's unlikely you'd care in practice. As to the technical differences, you can use type() to tell: >>> def f(): pass ... >>> class F: pass ... >>> type(f) <class 'function'> >>> type(F) <class 'type'> >>> type(range) <class 'type'> >>> type(map) <class 'type'> >>> type(open) <class 'builtin_function_or_method'> Note the last - built in functions are implemented in C, and behave slightly differently than *either* functions or classes. But you're unlikely to ever care. One example: >>> f.attr = 1 >>> open.attr = 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'builtin_function_or_method' object has no attribute 'attr' functions defined in Python can have user-defined attributes, builtins can't. Embrace duck typing, and only care about what you can do, not what type of object you're doing it to ;-) Paul -- https://mail.python.org/mailman/listinfo/python-list