I have just started learning Python & have come 开发者_如何转开发across "namespaces" concept in Python. While I got the jist of what it is, but am unable to appreciate the gravity of this concept.
Some browsing on the net revealed that one of the reasons going against PHP is that it has no native support for namespaces.
Could someone explain how to use namespaces & how this feature makes programming better (not just in Python, as I assume namespaces in not a concept limited to a particular language).
I am predominantly coming from Java and C programming backgrounds.
Namespace is a way to implement scope.
In Java (or C) the compiler determines where a variable is visible through static scope analysis.
In C, scope is either the body of a function or it's global or it's external. The compiler reasons this out for you and resolves each variable name based on scope rules. External names are resolved by the linker after all the modules are compiled.
In Java, scope is the body of a method function, or all the methods of a class. Some class names have a module-level scope, also. Again, the compiler figures this out at compile time and resolves each name based on the scope rules.
In Python, each package, module, class, function and method function owns a "namespace" in which variable names are resolved. Plus there's a global namespace that's used if the name isn't in the local namespace.
Each variable name is checked in the local namespace (the body of the function, the module, etc.), and then checked in the global namespace.
Variables are generally created only in a local namespace. The global
and nonlocal
statements can create variables in other than the local namespace.
When a function, method function, module or package is evaluated (that is, starts execution) a namespace is created. Think of it as an "evaluation context". When a function or method function, etc., finishes execution, the namespace is dropped. The variables are dropped. The objects may be dropped, also.
Namespaces prevent conflicts between classes, methods and objects with the same name that might have been written by different people.
Coming from a Java background you are probably familiar with how this is achieved using packages e.g. you might create a movieyoda.DateUtils
class and I can create a mikej.DateUtils
class and the package allows code using the classes to distinguish between them. (Python has something very similar.)
Namespaces were added to PHP in 5.3.0 but in earlier versions (and in other languages that don't provide namespaces) you would have to prefix your class and method names with something to reduce the risk of a name clash. e.g. a movieyoda_parse_file
function.
To understand namespaces, you also have to have some understanding of modules in Python. A module is simply a file containing Python code. This code can be in the form of Python classes, functions, or just a list of names. Each module gets it’s own global namespaces. So you can’t have two classes or two functions in the same module with the same name as they share the namespace of the module.
reference: http://bytebaker.com/2008/07/30/python-namespaces/
Namespaces provide a way for managing identifiers defined within a scope. In other words, they are used to map names to values (or references to the memory location to be more precise).
For example, in the context of a namespace the following expression
x = 10
will associate identifier x
to the memory location that holds object with value 10
.
In Python, there are essentially two "types" of namespaces; instance and class namespaces.
Instance Namespace manages the mapping between names and values within the scope of a individual object. On the other hand, there is a separate Class Namespace for every class defined in the source code. This type of namespace handles all the members which are shared by all instances of the object.
Example
Now consider the following example where for each member it is denoted whether it belongs to a class or instance namespace:
class Customer:
def __init__(self, first_name, last_name, email): # __init__ -> Customer Class Namespace
self._first_name = first_name # _first_name -> Instance Namespace
self._last_name = last_name # _last_name -> Instance Namespace
self._email = email # _email -> Instance Namespace
def get_full_name(self): # Customer Class Namespace
return f"{self._first_name} {self._last_name}"
class PremiumCustomer(Customer):
PREMIUM_MEMBERSHIP_COST = 4.99 # PremiumCustomer Class Namespace
class Subscription: # PremiumCustomer Class Namespace
def __init__(self, customer_email): # Subscription Class Namespace
self._customer_email = customer_email # Instance Namespace
def __init__(self, first_name, last_name, email, card_number): # PremiumCustomer Class Namespace
super().__init__(first_name, last_name, email)
self._card_number = card_number # _card_number -> Instance Namespace
def get_card_number(self): # PremiumCustomer Class Namespace
return self._card_number
I complete the answer of S.Lott.
I would say, namespace is a way to implement name management inside a scope, because a scope does more than name management.
In C the scopes are of 4 types: global, function, block and function-parameters(prototype). Each of these kinds can create one or more namespaces, depending on the needs. There are 4 ns in C -- tags for s/u/e -- ids for typenames, function names and var names -- parameters inside function prototype -- members and bitfields inside s/u.
Like that, tag identifiers and function names do not collide, but typenames defined by typedef can collide with variable names.
In python there is a builtin namespace that encloses the global ns, and the global ns is provided by the loaded module. The builtin ns contain variables. A symbol for a variable can define an object or a function -- for example, +
is defined there. The module's global ns lasts up to the termination.
See also that and of course that.
If you make a big program with someone else, you could write your own part of the program as you want. All variables in the file will be private, there will be no collisions. When you write PHP programs, it is easy to rewrite global variables by mistake. In python you can import other modules variables if you want, and they will be "global" on your module.
You could think one file one object in Python. When you write PHP programs you can achieve the same by writing classes with instance variables.
精彩评论