当我进行课程定义时,我总是去
Class A(object):
def __init__(self, arg):
self.arg = arg
def print_arg(self):
print(self.arg)
a = A('你好')
打印a.arg
'你好'
但我在第133和134行找到了什么 https://github.com/Pylons/webob/blob/master/src/webob/request.py让我想到我在A组中所做的与:
之间的区别Class B(object):
def __init__(self, arg):
self.__dict__['arg'] = arg
def print_arg(self):
print(self.arg)
b = B('再见')
打印b.arg
'再见'
答案 0 :(得分:5)
有几个主要含义:
使用self.__dict__
添加属性会绕过__setattr__
,这可能会因您在某些地方可能要避免的某种行为而过载。
In [15]: class Test(object):
...: def __init__(self, a, b):
...: self.a = a
...: self.__dict__['b'] = b
...: def __setattr__(self, name, value):
...: print('Setting attribute "{}" to {}'.format(name, value))
...: super(Test, self).__setattr__(name, value)
...:
In [16]: t = Test(1, 2)
Setting attribute "a" to 1
您可以看到没有为属性b
打印任何内容。
在某些情况下灵活性较低
In [9]: class WithSlots(object):
...: __slots__ = ('a',)
...: def __init__(self, a):
...: self.__dict__['a'] = a
...:
In [10]: instance = WithSlots(1)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-10-c717fcc835a7> in <module>()
----> 1 instance = WithSlots(1)
<ipython-input-9-2d23b670e0fc> in __init__(self, a)
2 __slots__ = ('a',)
3 def __init__(self, a):
----> 4 self.__dict__['a'] = a
5
AttributeError: 'WithSlots' object has no attribute '__dict__'
In [11]: class WithSlots(object):
...: __slots__ = ('a',)
...: def __init__(self, a):
...: self.a = a
...:
...:
In [12]: instance = WithSlots(1) # -> works fine
您不能在课程定义之外执行此操作。
答案 1 :(得分:2)
总体目的是规避Python设置变量的默认方式。此技术的特定用例是隐藏属性值。比较以下两个类:
class Exposed:
def __init__(self, x):
self._x = x
@property
def x(self):
rerurn self._x
class Hidden:
def __init__(self, x):
self.__dict__['x'] = x
@property
def x(self):
return self.__dict__['x']
这两个类都定义了一个只读属性x
。但是,第一个最终会有一个额外的_x
属性,可由用户直接修改,而第二个则不会。虽然Python中没有任何东西是真正的私有,但是第二类创建了一个真正的只读值的更好的近似值,并且它不会扩散不必要的可见属性。
答案 2 :(得分:1)
如果没有查看request
中的代码,可能会有目的地直接访问对象的__dict__
以绕过该对象的正常attribute lookup hierarchy。