对象的属性集和名称空间之间有什么区别?

问题描述

对象的属性集形成一个名称空间。要访问该属性,必须指定名称空间: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字典实现的,但通常不会以任何方式引起注意(性能除外),并且将来可能会发生变化。命名空间的示例包括:一组内置名称(包含诸如abs()之类的函数和内置异常名称);模块中的全局名称;以及函数调用中的 local 名称。 从某种意义上说,对象的属性集也构成一个名称空间。了解名称空间的重要一点是,不同名称空间中的名称之间完全没有关联

因此,正如@ user2357112 supports Monica在评论中所说:

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

肯特·约翰逊(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__','__eq__','__format__','__ge__','__get__','__getattribute__','__globals__','__gt__','__hash__','__init__','__init_subclass__','__kwdefaults__','__le__','__lt__','__module__','__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',[...]