python中更快的属性访问
考虑以下类别:python中更快的属性访问,python,pylint,Python,Pylint,考虑以下类别: class MyObject(object): __slots__ = ('_att1', '_att2') def __init__(self): self._att1 = None self._att2 = None @property def att1(self): """READ-ONLY property. """
class MyObject(object):
__slots__ = ('_att1', '_att2')
def __init__(self):
self._att1 = None
self._att2 = None
@property
def att1(self):
"""READ-ONLY property. """
return self._att1
@property
def att2(self):
"""att2 property description. """
return self._att2
@att2.setter
def att2(self, val):
self._att2 = val
使用属性装饰器的一个优点是,我们可以添加一些文档
a = MyObject()
help(a)
Help on MyObject in module __main__ object:
class MyObject(__builtin__.object)
| Methods defined here:
|
| __init__(self)
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| att1
| READ-ONLY property.
|
| att2
| att2 property description.
如果该类将由最终用户使用,则可以访问属性
通过使用属性
a.att2 = "new value"
但是,如果我要从MyObject
派生一个类,那么在派生类中使用“受保护”变量是否可以接受?就是
class Derived(MyObject):
__slots__ = ()
def __init__(self):
self._att1 = 1
self._att2 = 0
@property
def att2(self):
"""att2 adds 1 to itself in every call. """
self._att2 += 1
return self._att2
@att2.setter
def att2(self, val):
self._att2 = val
我知道,如果MyObject
是来自第三方的对象,则带有下划线的属性可能会发生更改,因此,如果这些属性发生更改,我的代码将中断。然而,由于我使用MyObject
作为基类,我认为将其用于我自己的派生类是很好的
我最近开始使用pylint
,这让我意识到我在派生类中使用的是“受保护”变量。我决定在这里发布一个问题的原因是想知道这样做是否可以接受,这样我就可以在pylint
中抑制这些警告。如果不是,那么处理这个问题的标准是什么
我想提出的另一点是关于属性访问的。什么会更快
a.att1
或
我的印象是,通过执行a.att1
python将首先查看对象字典,或插槽,就像我正在使用的示例一样。如果它在查找函数时不在那里(与的情况相同)。当在我的类定义中进行大量计算时,我宁愿访问字典或插槽中的内容,而不是使用装饰器定义的内容。在python社区中,这被认为是不好的做法吗?我之所以问这个问题,是因为pylint
的默认配置告诉我不是这样的,我希望在考虑好标准的情况下继续工作
编辑:
让我们尽量不要讨论\uuuuu插槽\uuuuu
和过早优化。如果可能的话
假设在我的原始帖子中,我没有使用\uuuuu slots\uuuu
,并且所有内容都在对象的字典中。简短回答:“过早优化是万恶之源。”
相信派林。看看你是否真的有性能问题。如果是,则分析并查找瓶颈。更改循环或数据结构可能更有效。简短回答:“过早优化是万恶之源。”
相信派林。看看你是否真的有性能问题。如果是,则分析并查找瓶颈。更改循环或数据结构可能更有效。带有下划线的属性不是“受保护的”,而是“私有的”——它们可能会发生更改。即使您的类是从它派生的。您应该使用父属性访问此数据
说到表演。当然,属性访问比属性访问慢一点,这仅仅是因为它涉及函数调用,但您不应该关心它。顺便说一句,它与
\uuu getattr\uuu
和所有这些东西都没有关系。属性也作为普通属性在字典中查找,它们只是实现了。带有下划线的属性不是“受保护的”,而是“私有的”——它们可能会发生更改。即使您的类是从它派生的。您应该使用父属性访问此数据
说到表演。当然,属性访问比属性访问慢一点,这仅仅是因为它涉及函数调用,但您不应该关心它。顺便说一句,它与
\uuu getattr\uuu
和所有这些东西都没有关系。属性也作为普通属性在字典中查找,它们只是实现了。Python在私有和受保护的类成员之间没有正式的区别。甚至私有和公共之间的区别也很弱,因为只要用户足够努力,任何东西都可以访问。如果私有与受保护的区别对您的应用程序有意义,您可以简单地记录\u foo
(或foo
)不是公共用户界面的一部分,但子类可以依赖它始终具有特定语义。(这些语义是什么取决于您。)
现在,我不知道为一个简单的只读属性这样做是否真的值得文档编写(函数调用开销可能不会太大,所以子类可以像其他所有人一样使用该属性)。但是,如果您有一个做了大量工作的属性,比如数据库查询或HTTP请求,那么将内部公开一点,以便子类只获取它们需要的部分,这可能是有意义的
如果您确实认为公开“protected”值是可取的,那么唯一的问题是是否应该在变量名前面加下划线。下划线对dir
以及文档生成工具有一些影响,但它不会改变代码的运行方式
所以这实际上是一个代码风格的问题,而且这两种方式都不重要。您可以不使用下划线并在文档中添加大的警告文本,这样用户就知道他们不应该弄乱内部结构,或者您可以使用下划线并使pylint警告静音(如果必要,强制为子类实现者提供一些额外的文档).Python在私有类成员和受保护类成员之间没有正式的区别。甚至私有和公共之间的区别也很弱,因为只要用户足够努力,任何东西都可以访问。如果私有与受保护的区别对您的应用程序有意义,您可以简单地记录
\u foo
(或foo
)不是公共用户界面的一部分,但子类可以依赖它始终具有特定语义。(这些语义是什么取决于您。)
现在,我不知道这是否真的值得
a._att1