【问题标题】:What is the difference between an object's set of attributes and its namespace?对象的属性集与其命名空间有什么区别?
【发布时间】:2020-12-15 02:57:09
【问题描述】:

对象的一组属性形成一个命名空间。要访问该属性,您必须指定命名空间:obj.attr。这是否意味着对象的属性只是在特定命名空间(对象名称)中定义的名称?还是有区别?例如,对模块中名称的引用是属性引用:在表达式 modname.function 中,modname 是一个模块对象,funcname 是它的一个属性,(see: 9.2) 但是当您定义如下函数时,函数的命名空间和它的属性有明显的区别:

>>> def aFunction():
    x=1
    y=2
    z=3
    #three names have been defined in the local namespace,
    #but aren't considered to be attributes of aFunction from what I understand.

我真的很困惑。有人可以详细说明一下并解释对象的命名空间及其属性之间的区别吗?

【问题讨论】:

  • 这里的问题是您对“对象的命名空间”的定义不明确的概念。函数有一个属性命名空间,每次调用函数都有一个局部变量命名空间。这些是不同的名称空间,但是通过考虑“对象的名称空间”,您最终会混淆这些概念。命名空间在概念上与对象关联的方式不止一种。

标签: python oop object namespaces


【解决方案1】:

请允许我引用文档:

命名空间是从名称到对象的映射。大多数命名空间目前都是作为 Python 字典实现的,但这通常不会以任何方式引起注意(性能除外),并且将来可能会发生变化。命名空间的示例有: 内置名称集(包含 abs() 等函数和内置异常名称);模块中的 global 名称;以及函数调用中的 local 名称。 从某种意义上说,对象的属性集也形成了一个命名空间。关于命名空间的重要知识是,不同命名空间中的名称之间绝对没有关系

所以,正如@user2357112 支持 Monica 在 cmets 中所说:

命名空间在概念上与对象关联的方式不止一种。

Kent Johnson 也 talked 说得很好:

另一种思考方式是,命名空间是名称所在的地方 抬头看。当您使用裸名(不是属性)时,会查找它 在本地命名空间中,然后是全局命名空间,然后是内置的 命名空间。例如:

y = 2  # Defines y in the global (module) namespace

def f():
  x = 1 # Defines x in the local (function) namespace

  # This looks up x, finds it in the local namespace
  # looks up abs, finds it in the built-in namespace
  print abs(x)

  # This looks up y, finds it in the global namespace
  print y

请注意,以上命名空间都没有相关的__dict__ 属性,命名空间映射不是那样存储的。

对象还定义了一种命名空间,其中定义了属性 并抬起头来。包含对象命名空间的字典就是它本身 存储为对象的属性,称为__dict__。所以__dict__ 是一个 对象属性存储方式的实现细节。

作为初学者,了解裸名的方式很重要 查找(localglobalbuilt-in 命名空间)并了解一下路 属性工作。您不必关心实施 __dict__等详细信息。

您可以使用dir() 函数探索不同的命名空间,其中:

不带参数,返回当前本地范围内的名称列表。使用参数,尝试返回该对象的有效属性列表。

def foo(a):
    if a == 3:
        b = 1
    else:
        c = 1
    print("Local function namespace: ", dir())


a = 2
b = 3
foo.custom_attr = "some attr"
foo(a)
foo(b)
print("Global namespace: ", dir())
print("foo object namespace via dir: ", dir(foo))
print("foo object namespace via __dict__: ", foo.__dict__)
print("Built-in namespace: ", dir(__builtins__))

输出:

Local function namespace:  ['a', 'c']
Local function namespace:  ['a', 'b']
Global namespace:  ['__builtins__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'b', 'foo']
foo object namespace via dir:  ['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'custom_attr']
foo object namespace via __dict__:  {'custom_attr': 'some attr'}
Built-in namespace:  ['ArithmeticError', 'AssertionError', 'AttributeError', [...]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-10
    • 1970-01-01
    • 2011-12-10
    • 2016-10-27
    • 2015-04-09
    • 2012-07-10
    • 1970-01-01
    相关资源
    最近更新 更多