Python 命名空间是关于什么的
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3913217/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What are Python namespaces all about
提问by Srikar Appalaraju
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.
我刚刚开始学习 Python,并在 Python 中遇到了“命名空间”概念。虽然我知道它是什么,但我无法理解这个概念的严重性。
Some browsing on the net revealed that one of the reasons going against PHP is that it has no native support for namespaces.
网上的一些浏览显示,反对 PHP 的原因之一是它没有对名称空间的本机支持。
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).
有人可以解释如何使用命名空间以及此功能如何使编程更好(不仅仅是在 Python 中,因为我假设命名空间的概念不限于特定语言)。
I am predominantly coming from Java and C programming backgrounds.
我主要来自 Java 和 C 编程背景。
采纳答案by S.Lott
Namespace is a way to implement scope.
命名空间是实现作用域的一种方式。
In Java (or C) the compiler determines where a variable is visible through static scope analysis.
在 Java(或 C)中,编译器通过静态作用域分析确定变量在哪里可见。
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.
在 C 中,作用域要么是函数的主体,要么是全局的,或者是外部的。编译器会为您解决这个问题,并根据作用域规则解析每个变量名称。在编译所有模块后,链接器会解析外部名称。
在 Java 中,作用域是一个方法函数的主体,或者是一个类的所有方法。一些类名也具有模块级作用域。同样,编译器在编译时计算出这一点,并根据作用域规则解析每个名称。
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.
在 Python 中,每个包、模块、类、函数和方法函数都拥有一个“命名空间”,变量名在其中解析。另外,如果名称不在本地命名空间中,则使用全局命名空间。
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 globaland nonlocalstatements can create variables in other than the local namespace.
变量通常只在本地命名空间中创建。该global和nonlocal语句可以比本地命名空间创建其他变量。
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.
当一个函数、方法函数、模块或包被评估(即开始执行)时,会创建一个命名空间。将其视为“评估上下文”。当函数或方法函数等完成执行时,命名空间将被删除。变量被丢弃。对象也可能被丢弃。
回答by shahjapan
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.
要理解命名空间,您还必须对 Python 中的模块有所了解。模块只是一个包含 Python 代码的文件。此代码可以采用 Python 类、函数或只是名称列表的形式。每个模块都有自己的全局命名空间。所以你不能在同一个模块中有两个类或两个函数,因为它们共享模块的命名空间。
reference: http://bytebaker.com/2008/07/30/python-namespaces/
回答by mikej
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.DateUtilsclass and I can create a mikej.DateUtilsclass and the package allows code using the classes to distinguish between them. (Python has something very similar.)
来自 Java 背景的您可能熟悉如何使用包来实现这一点,例如,您可以创建一个movieyoda.DateUtils类,我可以创建一个mikej.DateUtils类,并且包允许代码使用这些类来区分它们。(Python 有一些非常相似的东西。)
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_filefunction.
命名空间是在 5.3.0 中添加到 PHP 中的,但在早期版本中(以及在其他不提供命名空间的语言中),您必须在类和方法名称前加上一些前缀以降低名称冲突的风险。例如一个movieyoda_parse_file函数。
回答by Adam Wallner
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.
如果您与其他人一起制作了一个大程序,您可以根据需要编写自己的程序部分。文件中的所有变量都是私有的,不会有冲突。在编写 PHP 程序时,很容易错误地重写全局变量。在 python 中,您可以根据需要导入其他模块变量,它们将在您的模块上是“全局的”。
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.
你可以认为一个文件是 Python 中的一个对象。当您编写 PHP 程序时,您可以通过编写带有实例变量的类来实现相同的目的。
回答by alinsoar
I complete the answer of S.Lott.
我完成了 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.
在 C 中,作用域有 4 种类型:全局、函数、块和函数参数(原型)。根据需要,这些类型中的每一种都可以创建一个或多个命名空间。C 中有 4 ns -- s/u/e 的标签 -- 类型名、函数名和 var 名称的 id -- 函数原型内的参数 -- s/u 内的成员和位域。
Like that, tag identifiers and function names do not collide, but typenames defined by typedef can collide with variable names.
像这样,标签标识符和函数名不会冲突,但 typedef 定义的类型名会与变量名冲突。
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.
在python中有一个内置的命名空间,它包含了全局ns,全局ns由加载的模块提供。内置 ns 包含变量。变量的符号可以定义一个对象或一个函数——例如,+在那里定义。模块的全局 ns 持续到终止。
回答by Giorgos Myrianthous
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 xto the memory location that holds object with value 10.
将标识符x与保存对象的内存位置相关联10。
In Python, there are essentially two "types" of namespaces; instance and class namespaces.
在 Python 中,本质上有两种“类型”的命名空间;实例和类命名空间。
Instance Namespacemanages the mapping between names and values within the scope of a individual object. On the other hand, there is a separate Class Namespacefor 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

