两者之间的区别自身参数=arg和self.Python中的\uu dict_u['arg']=arg

2024-06-01 21:41:44 发布

您现在位置:Python中文网/ 问答频道 /正文

当我做一个类定义时,我总是去

Class A(object):
    def __init__(self, arg):
        self.arg = arg
    def print_arg(self):
        print(self.arg)

a = A('hello')

print a.arg

'hello'

但是我在第133行和第134行找到的 of https://github.com/Pylons/webob/blob/master/src/webob/request.py让我想我在甲级课上所做的有什么区别:

^{pr2}$

b = B('goodbye')

print b.arg

'goodbye'


Tags: ofhttpsselfgithubcomhello定义object
3条回答

在没有查看request中的代码的情况下,对对象{}的直接访问可能是故意放在那里的,以避开该对象的正常attribute lookup hierarchy。在

有几个主要含义:

  1. 使用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打印任何内容。

  2. 它在某些情况下不太灵活

    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
    
  3. 你不能在类定义之外这样做。

总的目的是绕过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中没有什么是真正私有的,但是第二个类创建了一个更接近真实只读值的方法,并且它不会增加不必要的可见属性。在

相关问题 更多 >