I have heard a lot about namespace as a feature for programming language. Thus, can not help thinking:
Does Python have so called namespace feature?
Quote from Python documentation:
A namespace is a mapping from names to objects. Most namespaces are currently implemented as Python dictionaries, but that’s normally not noticeable in any way (except for performance), and it may change in the future. Examples of namespaces are: the set of built-in names (containing functions such as abs(), and built-in exception names); the global names in a module; and the local names in a function invocation. In a sense the set of attributes of an object also form a namespace. The important thing to know about namespaces is that there is absolutely no relation between names in different namespaces; for instance, two different modules may both define a function maximize without confusion — users of the modules must prefix it with the module name.
For a good overview, see the "Python Scopes and Namespaces" section of the Python tutorial at https://docs.python.org/2/tutorial/classes.html#python-scopes-and-namespaces.
Related
For start, sorry for my bad English.
Recently I read book called "elegant objects" by Yegor Bugayenko. One of the topics in this book is dedicated to using of objects instead of public constants. Author writes that public constants is a pure evil. There are a lot of reasons for this. For example, using of public constants breaks incapsulation - if we want to change this contant we need to know how classes of our package using this constant. If two classes in project are using this constant in its own way we need to change code of this two classes if we change constant.
Author suggests that instead of using global constants we need to create objects and that's allows us to change code only in one place. I will give an example below.
I already read similar topics on stackoverflow, but did not find the answer about best practices or use cases. Is the use of objects better than creating a global variable in some file, for example "settings.py"?
Is this
class WWStartDate:
date_as_string = '01.09.1939'
def as_timestamp(self):
# returns date as timestamp
def as_date_time(self):
# returns date as datetime object
better than this stored in some file inside package conf.py for example:
DATE_STRING = '01.09.1939'
if we are talking about using this date in several classes of our package?
After reading of this book I decided that objects are much better, but I see a lot of cases when developers of framework or library force us to use global variables. So It is not that simple as I can see. Why, for example, django use this approach? I am talking about file settings.py.
I think that by creating a class for a constant to offer itself in different forms to different (other) classes you are overengineering your constants. Why does the constant have to know how it's being used? Does math.pi know how it is being used? It actually has some methods because it's a float object. Nothing specific to the pi constant. Besides, when you do it, you couple the constant to other classes, and when they change their uses you may have to update the constant class. Now that's a bad idea. You want them decoupled. Each class (and only the class) should know what it is doing with the constant.
This is not to say that a wrapping class can't be useful sometimes, specially if you group related constants. But them you can use Enums too.
And globals in a module are only globals in that module. When imported you are either using copies or (qualified) linked names. But even in the linked case if you change the imported value (which you shouldn't because you say it is constant) using qualification, and a different module is importing the same value, it does not see the changes you made. They are using different namespaces. This is not the usual "global variable" concept, when we say globals are evil.
I wasn't looking what I had previously written on the line so I accidently declared a variable in ipython as:
np.zerosn=10
Surprisingly this was allowed. So I thought that maybe it was because you can name use periods in your variable names, but that is not the case. So I'm wondering what is actually happening. Is this adding a new variable to the numpy module?
Yes.
In general, (most/many) python objects have dynamic attribute spaces, and you can stick whatever you want onto them whenever you want. And modules are just objects. Their attribute space is essentially the same as their global scope.
Pure python functions are another (perhaps surprising) example of something onto which you can stick arbitrary attributes, though these are not associated with the function's local scope.
Most 'builtin' types (i.e. those which are implemented in extension modules, rather than those that are found in the __builtins__ module) and their instances, do not have dynamic attribute spaces. Neither do pure python types with __slots__.
In regards to naming conventions for class attributes, PEP 8 states:
__double_leading_and_trailing_underscore__: "magic" objects or attributes that live in user-controlled namespaces. E.g. __init__, __import__ or __file__. Never invent such names; only use them as documented.
Does this imply to never use this convention or only use in a "user-controlled namespace."
I have seen this used in other libraries not directly included within Python a few times. From what I gather, using this convention is more specific to implementing an API.
A couple of examples would be providing an __acl__ to a class in Pyramid, or adding __tablename__ to a class in SQLAlchemy.
Is using this convention in the context of an API OK, or should it only ever be used / reserved for Python?
Pyramid and SQLAlchemy have disobeyed the instruction not to invent such names.
It's not clear to me what you mean by "using this convention in the context of an API", but once they've invented the name, you don't have much choice but to use it as documented by them.
There's no difference between you inventing such names, and inventing them only in user-controlled namespaces. Since you're a user of Python, any namespace that you could put the name into is user-controlled. If you're modifying the Python source to add a new extension to the language that requires some "magic" name, then you can invent one. I expect if you're doing this, you'll usually be in communication with GvR one way or another, so you can ask his opinion directly :-)
What's happening here is that the library authors want a name that none of their users will use by accident to mean something else. The Python language also wants names that no user will use by accident to mean something else, so it "reserves" names of a particular format for use by the language. But then the library-writer has decided to "steal" one of those reserved names and use it anyway, because they feel that's the best way to avoid a clash with one of their users. They have tens of thousands of users, most of whom they don't know anything about. But there's only one Python language spec, and they have access to it. So if a clash occurs the library developers will know about it, which is the plus side, but it will be their fault and difficult to fix, which is the minus side.
Perhaps they're hoping that by using it, the have de facto reserved it for themselves, and that GvR will choose never to use a name that a popular library has already used. Or perhaps they've discussed it on the relevant mailing lists and obtained an exception to the usual rule -- I don't know whether there's a process for that.
Referring to Python PEP8:
__double_leading_and_trailing_underscore__ : "magic" objects or attributes that live in user-controlled namespaces. E.g. __init__,
__import__ or __file__. Never invent such names; only use them as documented.
I browsed through many questions related to the use of underscores in Python and I think I have understood the answers to most of them (things like private attributes, name mangling, etc.). I think I have also understood the aforementioned use of double leading and trailing underscores. I guess it's for protecting functions like __init__ which are similar to constructors in languages like C++ and Java.
But then shouldn't it be called community-controlled namespaces (by community I mean the Python community)? What does the author mean when he says user-controlled namespaces? In fact it seems the intent is the opposite: users should not (normally) trifle with these namespaces.
User-controlled namespaces means namespaces where a user, programming in Python, controls what names exist and what values they have. In other words, basically user-created APIs. What it means is that you shouldn't design an API that relies on new __doubleunderscore_names__ that you make up.
"Namespace" here does not refer to the naming convention but to the actual programming scope. For instance, each function has a local namespace for its local variables; a module has a global namespace for its global variables; etc. Users absolutely will use these namespaces -- you will create your own variables, classes, functions, etc.. What it's saying is that you shouldn't make up new magic-looking names and put them in your namespaces.
User-controlled namespaces are namespaces like global variables or object attributes. A Python programmer can put whatever names he or she so chooses into those namespaces; community disapproval can't stop it. Double-dunder names like __init__ and __file__ live in those namespaces along with ordinary names defined by programmers. The PEP 8 recommendation is that users not create non-standard names that look like the standard magic names.
In cherryPy for example, there are files like:
__init__.py
_cptools.py
How are they different? What does this mean?
__...__ means reserved Python name (both in filenames and in other names). You shouldn't invent your own names using the double-underscore notation; and if you use existing, they have special functionality.
In this particular example, __init__.py defines the 'main' unit for a package; it also causes Python to treat the specific directory as a package. It is the unit that will be used when you call import cherryPy (and cherryPy is a directory). This is briefly explained in the Modules tutorial.
Another example is the __eq__ method which provides equality comparison for a class. You are allowed to call those methods directly (and you use them implicitly when you use the == operator, for example); however, newer Python versions may define more such methods and thus you shouldn't invent your own __-names because they might then collide. You can find quite a detailed list of such methods in Data model docs.
_... is often used as 'internal' name. For example, modules starting with _ shouldn't be used directly; similarly, methods with _ are supposedly-private and so on. It's just a convention but you should respect it.
These, and other, naming conventions are described in detail in Style Guide for Python Code - Descriptive: Naming Styles
Briefly:
__double_leading_and_trailing_underscore__: "magic" objects or attributes that live in user-controlled namespaces. E.g.__init__, __import__ or __file__. Never invent such names; only use them as documented.
_single_leading_underscore: weak "internal use" indicator. E.g. from M import * does not import objects whose name starts with an underscore.
__init__.py is a special file that, when existing in a folder turns that folder into module. Upon importing the module, __init__.py gets executed. The other one is just a naming convention but I would guess this would say that you shouldn't import that file directly.
Take a look here: 6.4. Packages for an explanation of how to create modules.
General rule: If anything in Python is namend __anything__ then it is something special and you should read about it before using it (e.g. magic functions).
The current chosen answer already gave good explanation on the double-underscore notation for __init__.py.
And I believe there is no real need for _cptools.py notation in a filename. It is presumably an unnecessary extended usage of applying the "single leading underscore" rule from the Style Guide for Python Code - Descriptive: Naming Styles:
_single_leading_underscore: weak "internal use" indicator. E.g. from M import * does not import objects whose name starts with an underscore.
If anything, the said Style Guide actually is against using _single_leading_underscore.py in filename. Its Package and Module Names section only mentions such usage when a module is implemented in C/C++.
In general, that _single_leading_underscore notation is typically observed in function names, method names and member variables, to differentiate them from other normal methods.
There is few need (if any at all), to use _single_leading_underscore.py on filename, because the developers are not scrapers , they are unlikely to salvage a file based on its filename. They would just follow a package's highest level of APIs (technically speaking, its exposed entities defined by __all__), therefore all the filenames are not even noticeable, let alone to be a factor, of whether a file (i.e. module) would be used.