8

Was just thinking about Python's dict "function" and starting to realize that dict isn't really a function at all. For example, if we do dir(dict), we get all sorts of methods that aren't include in the usual namespace of an user defined function. Extending that thought, its similar to dir(list) and dir(len). They aren't function, but really types. But then I'm confused about the documentation page, http://docs.python.org/2/library/functions.html, which clearly says functions. (I guess it should really just says builtin callables)

So what gives? (Starting to seem that making the distinction of classes and functions is trivial)

eyquem
  • 26,771
  • 7
  • 38
  • 46
  • 7
    [If it looks like a function and acts like a function, then it's a function](http://stackoverflow.com/a/4205163/489590), right? – Brian Cain Aug 30 '13 at 14:04
  • 1
    Note that `dir()` was never intended to give a *complete* overview of available functions. `dir(type)` gives you a lot of those same functions. – Martijn Pieters Aug 30 '13 at 14:06
  • I'd agree that the aspects of these point more into the direction of classes than of functions. After all you can do things like `isinstance(x, dict)` which shouldn't work if `dict` was a pure function. – Alfe Aug 30 '13 at 14:06
  • 1
    I personally think that they just called it a function. Kinda like how I've seen some people call this an array or list: `('a', 'b')`, when its technical term is "tuple". –  Aug 30 '13 at 14:10
  • My opinion is that in some places of the doc, it is poorly redacted. I've the same opinion as iCodez: the redactor wrote this word without really thinking to it. And that's right that it's potentially predisposes to misunderstanding – eyquem Aug 30 '13 at 18:20
  • Because of a comment from Codie CodeMonkey, I took the liberty to do a tiny edit of your question concerning the word 'function' at the beginning – eyquem Aug 30 '13 at 21:43
  • 1
    Note that the sentence has become ``The Python interpreter has a number of functions and types built into it that are always available.`` in the documentation of the versions 3.x – eyquem Aug 30 '13 at 21:46

4 Answers4

5

It's a callable, as are classes in general. Calling dict() is effectively to call the dict constructor. It is like when you define your own class (C, say) and you call C() to instantiate it.

Hammerite
  • 21,755
  • 6
  • 70
  • 91
  • 2
    I understand its a callable, but then why are we calling them `functions` on the documentation page? It would seem that having the names `class` and `function` is quite trivial. –  Aug 30 '13 at 14:06
  • 1
    @PhillipCloud I understand the difference, but surely you can admit that its a bit misleading to have the documentation page say builtin functions when user defined functions have `func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name'` and none of the builtins do. –  Aug 30 '13 at 14:19
  • @EdgarAroutiounian The constructor is really a method on the `type` object. This method is of course a special kind of function. It's definitely *not* trivial to make the distinction between a function (not method) created by a `def` statement and a class and its constructor. The fact that you think this distinction is trivial implies that you might not have written many functions and/or classes. I also don't think calling `dict` a function is confusing if you understand the difference between classes and functions and how classes are related to callables. – Phillip Cloud Aug 30 '13 at 14:25
  • 1
    @PhillipCloud Pedantic or not, its an issue of being clear. Reread my post, I never said that that the distinction of functions and classes is indeed trivial, rather that it, at least superficially, could `seem` to be the case and that perhaps the documentation for the builtin functions page is better called the builtin callables page. In any case, I'm not sure what benefit Stack gets from pointless speculation about how many classes and or function an OP has written, maybe you'd like to speculate how many lines of code OPs have written as well? –  Aug 30 '13 at 14:30
  • @Philip Cloud Having read your user's page, you seem to be someone able to go deep into details and hard questions. So I wonder why you seem to support the idea that being unrigorous and unprecise isn't a serious point. I find your arguments weak and inappropriate. – eyquem Aug 30 '13 at 18:04
  • @Philip Cloud I dont't find difficult to perceive the distinction between a function and a class (see the answer of TokenMacGuy). I don't see the link between this point and the number of functions ans classes ever written by someone. I don't find clever to swim in confusion on words, calling function an object that is not a function, and particularly if one has well understand the (trivial) difference between a class and a function. – eyquem Aug 30 '13 at 18:06
  • @Cloud In fact, it seems to me that this confusion doesn't hurt you because of the underlying ideas I perceive as yours: you seem to consider that the essence of a class is its constructor (I mean ``__init__`` I think you mean the same) and that, consequently, differentiating a function from a class is basically differentiating between a function and a method, this latter distinction being non trivial to understand. – eyquem Aug 30 '13 at 18:07
  • @Cloud As it seems to me, it's true that people in general don't perceive clearly that a method isn't a kind of function but an object with strong characteristics that make it strongly different, though based on, a function. – eyquem Aug 30 '13 at 18:08
  • _"a look at the implementation can clarify matters. When an instance attribute is referenced, its class is searched. If the name denotes a function object, a method object is created by packing (pointers to) the instance object and the function object just found together in an abstract object: this is the method object. When the method object is called with an argument list, a new argument list is constructed from the instance object and the argument list, and the function object is called with this new argument list."_ (http://docs.python.org/2/tutorial/classes.html#method-objects) – eyquem Aug 30 '13 at 18:10
  • @Cloud Making vague link between notions unsufficiently understood doesn't constitute a valid and useful conceptions. - By the way, functions are not only user-defined objects, there are built-in functions (in the precise sense of this word) in the language, just see in the modules, there are plenty of them. - Last, classes are not RELATED to callables, they ARE callables. You have a peculiar manner to twist the notions. – eyquem Aug 30 '13 at 18:11
  • 1
    @Edgar I am completly on the same line as you, I don't like confusion and lack of precision in use of the terms – eyquem Aug 30 '13 at 18:12
3

One way that dict is special, compared to, say, sum, is that though both are callable, and both are implemented in C (in cpython, anyway), dict is a type; that is, isinstance(dict, type) == True. This means that you can use dict as the base class for other types, you can write:

class MyDictSubclass(dict):
    pass

but not

class MySumSubclass(sum):
    pass

This can be useful to make classes that behave almost like a builtin object, but with some enhancements. For instance, you can define a subclass of tuple that implements + as vector addition instead of concatenation:

class Vector(tuple):
    def __add__(self, other):
        return Vector(x + y for x, y in zip(self, other))

Which brings up another interesting point. type is also implemented in C. It's also callable. Like dict (and unlike sum) it's an instance of type; isinstance(type, type) == True. Because of this weird, seemingly impossible cycle, type can be used to make new classes of classes, (called metaclasses). You can write:

class MyTypeSubclass(type):
    pass

class MyClass(object):
    __metaclass__ = MyTypeSubclass

or, in Python 3:

class MyClass(metaclass=MyTypeSubclass):
    pass

Which give the interesting result that isinstance(MyClass, MyTypeSubclass) == True. How this is useful is a bit beyond the scope of this answer, though.

SingleNegationElimination
  • 151,563
  • 33
  • 264
  • 304
1

dict() is a constructor for a dict instance. When you do dir(dict) you're looking at the attributes of class dict. When you write a = dict() you're setting a to a new instance of type dict.

I'm assuming here that dict() is what you're referring to as the "dict function". Or are you calling an indexed instance of dict, e.g. a['my_key'] a function?

Codie CodeMonkey
  • 7,669
  • 2
  • 29
  • 45
  • I think it's better to call it the `dict()` constructor, since it's more than just an initialization function. It also allocates a new instance. – Codie CodeMonkey Aug 30 '13 at 14:21
  • @Codie CodeMonkey I wonder if your wish of calling ``dict()`` a constructor isn't influenced by other languages you certainly know. I don't agree with this wish. Seeing in the doc's index, entry ``constructor`` leads to ``object.__init__(self[, ...])``. Things are enough complex without adding complexity by giving self definition for words that have already one. – eyquem Aug 30 '13 at 17:12
  • @eyquem, could well be! So the proper name for `dict()` is the `dict` function? – Codie CodeMonkey Aug 30 '13 at 19:30
  • @Codie CodeMonkey I don't understand your comment. Strictly speaking, ``dict()`` isn't neither a function nor a class nor any other object, it's an expression that means a call. Now, I, as many people, I habitually write ``f()`` to designate a function of name ``f`` because, though not perfectly strict, it visually brings the message that it's a function. That makes me realize that I would probably write ``A(...]``, where **A** is a class, if there would be a particular interest to show the arguments passed to **A**, but I think I usually simply write ``A`` in other case. – eyquem Aug 30 '13 at 20:25
  • @Codie CodeMonkey This lack of full strictness concerns the written representation of an object, not the naming of the object as Philip Cloud wish to justify – eyquem Aug 30 '13 at 20:29
  • 1
    @eyquem, Your point that Python doesn't refer to `dict()` as a constructor is a good one. I simply asked what the appropriate name for such a construct is, as the OP used the phrase 'dict function'. I did a brief search and found that docs.python.org uses "instantiation operation" (http://docs.python.org/3/tutorial/classes.html#class-objects). I think that's what I was looking for. – Codie CodeMonkey Aug 30 '13 at 21:09
  • @Codie CodeMonkey I nod. ``dict()`` is an instantiation because object of name ``dict`` is a class. – eyquem Aug 30 '13 at 21:38
0

Note that calling dir on the constructor dict.__init__

dir(dict.__init__)

gives you what you would expect, including the same stuff as you'd get for any other function. Since a call to the dict() constructor results in a call to dict.__init__(instance), that explains where those function attributes went. (Of course there's a little extra behind-the-scenes work in any constructor, but that's the same for dicts as for any object.)

Mark R. Wilkins
  • 1,282
  • 7
  • 15