-5

I know that when a module or even if a specific object in that module is imported -- from foo import bar -- that entire module is evaluated first. But I was just being curious that if we define an __init__ or a __new__ inside that module would it have an specially meaning or treatment like it does inside a class and a package? And why so?

Bleeding Fingers
  • 6,993
  • 7
  • 46
  • 74
  • `__init__` and `__new__` functions don't have any meaning inside a package. – abarnert May 28 '13 at 21:14
  • @abarnert well we do have a `__init__.py ` – Bleeding Fingers May 28 '13 at 21:15
  • 1
    Yes, but that's not a function, or a method. – abarnert May 28 '13 at 21:17
  • @abarnert question updated. It gets executed though. Akin to function call? Different semantics I guess – Bleeding Fingers May 28 '13 at 21:22
  • It's not a very close kin to a function call. A module contains code that gets executed when at first import time—that is, exactly once, when the module's definition is evaluated. A function contains code that does _not_ get executed when the function's definition is evaluated, but instead gets executed each time the resulting function is later called. A module is not a `callable`, as you'd see immediately if you typed, e.g., `sys()` at the interactive prompt. – abarnert May 28 '13 at 21:27

3 Answers3

2

No. There is a module class, and modules are instances of this class, but it's internal to Python. Defining magic methods in a module won't add them to the module class, and they won't do anything special at import time.

kindall
  • 178,883
  • 35
  • 278
  • 309
  • This is a bit misleading. The key point here is that the global functions in a module are not methods of the module object. If you _do_ define `__init__` and `__new__` methods in the module class (or, rather, in a subclass that you import-hook or monkeypatch in), they'll work. – abarnert May 28 '13 at 21:16
  • then why are packages treated differently? Referring to `__init__.py` – Bleeding Fingers May 28 '13 at 21:17
  • @hus787: They aren't treated differently. Who said they were? – abarnert May 28 '13 at 21:18
  • @abarnert when a package is imported the `__init__.py` is executed. But inside a module the __init__ is not called/executed. Therefore seemingly different as per observation. – Bleeding Fingers May 28 '13 at 21:25
  • `__init__.py` merely has the same name as the `__init__()` method. A file is, however, not a method, so there should be no confusion. – kindall May 28 '13 at 21:28
  • @abarnert, good point, I've updated a bit. – kindall May 28 '13 at 21:29
  • @hus787: And if there's an `__init__` function inside `__init__.py`, it doesn't get executed either. A package _is_ a module. I don't see what you're not getting here. – abarnert May 28 '13 at 21:29
2

Putting it loosely, modules do not have methods.

More strictly, each module is an instance of some class, usually builtins.module (although you can replace this with an import hook or by monkeypatching), and that class does of course have methods. But the module's global functions are not methods of the module object.

You can verify this pretty easily by just printing out type(foo.func). It's a function, not a bound method of the foo instance.

On top of that, even if module global functions were instance methods, that wouldn't make any difference, because __init__ is checked in the class dictionary, not the instance dictionary. If you think about it, there's no way it could possibly be otherwise, because you don't have an instance dictionary to check until __init__ returns. So, this could only possibly work if each module were a class object (and instance of type), which they obviously aren't.


Your confusion with __init__.py is a red herring. Files are not functions, much less methods, and neither files nor modules can be called.


If you want the rigorous definitions: classes and modules are defined here. As you can see, the __new__ method is a feature specific to classes. Its behavior is defined here. Note that __init__ is actually called as a consequence of object.__new__, so it's not even technically defined for classes—but it certainly isn't defined for anything else.

Meanwhile, __init__.py is defined here. (Note that, as of Python 3.2, this is just a convention used by the default importers for regular packages, not actually part of the language itself.)

The two features have nothing in common except naming and some vague similarities. Maybe the naming was a mistake, but I think more people get useful intuitions out of the naming than are confused. (At any rate, since it goes back to the ni module for Python 1.3, I doubt it will be changed anytime soon.)

abarnert
  • 354,177
  • 51
  • 601
  • 671
0

I think you could make a class that had __init__() and/or __new__() methods module-like by doing something similar to what is done in my answer to the unrelated question Can I prevent modifying an object in Python?

Community
  • 1
  • 1
martineau
  • 119,623
  • 25
  • 170
  • 301