- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在编写一个配置卷的存储自动化模块。我没有传递在存储 Controller 上实际创建卷所需的六个或更多参数,而是使用 __slots__
创建了一个参数类,它被传递到 create 方法中,如下所示:
from mock import Mock
from six import with_metaclass
class VolumeParameterMeta(type):
def __new__(mcs, name, bases, dct):
# set __slots__ docstrings here?
return super(VolumeParameterMeta, mcs).__new__(mcs, name, bases, dct)
class VolumeParameter(with_metaclass(VolumeParameterMeta, object)):
__slots__ = ('name', 'size', 'junctionPath', 'svmName', 'securityStyle'
'spaceReserve')
def __init__(self, name):
self.name = name
class Volume(object):
def __init__(self, driver, name):
self.driver = driver
self.name = name
@classmethod
def create(cls, driver, param):
# do sanity check on param (volume not too large, etc)
driver.provision(param)
return cls(driver, param.name)
if __name__ == '__main__':
param = VolumeParameter('volume1')
param.svmName = 'vserver1'
param.junctionPath = '/some/path'
param.size = 2 ** 30
param.spaceReserve = param.size * 0.1
param.securityStyle = 'mixed'
volume = Volume.create(driver=Mock(), param=param)
除了一个小异常(exception),上面的例子效果很好。如何将文档字符串添加到参数类中的描述符并不明显。 似乎元类应该是可能的,但是在实例化元类时未定义描述符。
我敏锐地意识到有些人可能不同意我使用 __slots__
的副作用,但我喜欢它有助于消除拼写错误。尝试设置一个不存在的参数,并引发 boom,AttributeError
。全部没有任何样板代码。让它在卷创建时失败可以说是更 Pythonic,但结果将是使用默认值而不是拼写错误的参数。这实际上是一个无声的失败。
我意识到可以简单地扩展参数类文档字符串,但是 pydoc
和其他文档构建脚本的结果是类的大型自由格式文档字符串,空 每个描述符的文档字符串。
肯定有一种方法可以为 __slots__
创建的描述符定义文档字符串吗?也许除了插槽之外还有另一种方式?可变的 namedtuple
或类似的?
最佳答案
不,没有选项可以将文档字符串添加到为 __slots__
中定义的名称生成的描述符对象。在这方面,它们就像常规的非描述符属性。
在没有插槽的常规对象上,最多可以添加注释并设置默认值:
class VolumeParameter(object):
# the name of the volume (str)
name = ''
# volume size in bytes (int)
size = 0
# ...
即使您将所有这些属性都声明为 __slots__
,这同样适用。
您可以以 property
对象的形式将每个槽“包装”在另一个描述符中:
class VolumeParameterMeta(type):
@staticmethod
def _property_for_name(name, docstring):
newname = '_' + name
def getter(self):
return getattr(self, newname)
def setter(self, value):
setattr(self, newname, value)
def deleter(self):
delattr(self, newname)
return newname, property(getter, setter, deleter, docstring)
def __new__(mcs, name, bases, dct):
newslots = []
clsslots = dct.pop('__slots__', ())
slotdocs = dct.pop('__slot_docs__', {})
if isinstance(clsslots, str):
clsslots = clsslots.split()
for name in clsslots:
newname, prop = mcs._property_for_name(name, slotdocs.get(name))
newslots.append(newname)
dct[name] = prop
if newslots:
dct['__slots__'] = tuple(newslots)
return super(VolumeParameterMeta, mcs).__new__(mcs, name, bases, dct)
class VolumeParameter(with_metaclass(VolumeParameterMeta, object)):
__slots__ = ('name', 'size', 'junctionPath', 'svmName', 'securityStyle'
'spaceReserve')
__slot_docs__ = {
'name': 'the name of the volume (str)',
# ...
}
请注意,这几乎使类的描述符数量翻了一番:
>>> pprint(VolumeParameter.__dict__)
mappingproxy({'__doc__': None,
'__module__': '__main__',
'__slots__': ('_name',
'_size',
'_junctionPath',
'_svmName',
'_securityStylespaceReserve'),
'_junctionPath': <member '_junctionPath' of 'securityStylespaceReserve' objects>,
'_name': <member '_name' of 'securityStylespaceReserve' objects>,
'_securityStylespaceReserve': <member '_securityStylespaceReserve' of 'securityStylespaceReserve' objects>,
'_size': <member '_size' of 'securityStylespaceReserve' objects>,
'_svmName': <member '_svmName' of 'securityStylespaceReserve' objects>,
'junctionPath': <property object at 0x105edbe08>,
'name': <property object at 0x105edbd68>,
'securityStylespaceReserve': <property object at 0x105edb098>,
'size': <property object at 0x105edbdb8>,
'svmName': <property object at 0x105edb048>})
但现在你的属性至少有文档字符串:
>>> VolumeParameter.name.__doc__
'the name of the volume (str)'
关于python - 将文档字符串添加到 __slots__ 描述符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39171672/
首先让我说我了解槽和元类在 Python 中的工作方式。玩弄这两个,我遇到了一个有趣的问题。这是一个最小的例子: def decorator(cls): dct = dict(cls.__di
__slots__ 的目的是什么?在 Python 中——尤其是关于我什么时候想使用它,什么时候不想使用它? 最佳答案 In Python, what is the purpose of __slot
我在 Python 的输入系统和 __slots__ 之间有冲突。这是一个可重现的小例子。 from typing import TypeVar, Generic, Sequence T = Type
class Foo(object): __slots__ = ('a',) class Bar(Foo): @property def a(self): ret
我有一节课 __slots__ : class A: __slots__ = ('foo',) 如果我创建一个子类而不指定__slots__,子类将有一个__dict__: class B(A
我正在开发一个需要通过 __init__ 注入(inject)来为其赋予 __dict__ 属性的类,如下所示: class Torrent(Model): def __init__(self
我听说 __slots__ 通过避免字典查找使对象更快。我的困惑来自于 Python 是一种动态语言。在静态语言中,我们通过编译时优化将索引保存在我们运行的指令中,从而避免了对 a.test 的字典查
我需要用 None 初始化一个实例的所有插槽。如何获取派生类的所有插槽? 示例(不起作用): class A(object): __slots__ = "a" def __init__
所以,我正在阅读一些关于 Python 中元类的内容,以及如何使用 type()的三参数 alter-ego 用于动态创建类。但是,第三个参数通常是 dict。初始化要创建的类'__dict__变量。
考虑以下代码: from weakref import ref class Klass(object): # __slots__ = ['foo'] def __init__(self
通过学习《Python类变量和实例变量》一节,了解了如何动态的为单个实例对象添加属性,甚至如果必要的话,还可以为所有的类实例对象统一添加属性(通过给类添加属性)。 那么,Python 是否也允许动态地
早上好 我在尝试在我的一门类(class)中使用 __ 插槽 __ 时遇到问题。我想用它来优化 Classifier 对象的多个实例的创建。我正在使用 Python 3.7.1。 这行得通 class
当我运行这个(2.7.3)时,我得到这个输出: 'Slotted1' object has no attribute 'c' attribute c added to 我不明白 Slotted1 和
最近在学习Python,但是我有一个关于__slots__的问题。我认为是为了限制Class中的参数,同时也限制Class中的方法? 例如: from types import MethodType
最近给 friend 讲解了__slots__的用法。我想向他展示结果并使用了以下代码: import sys class Foo: __slots__ = 'a', 'b' def
我一直在玩弄 __slots__ 并稍微搜索一下,但我仍然对某些细节感到困惑: 我知道 __slots__ 生成某种描述符: >>> class C: ... __slots__ = ('x'
在类中创建结果对象时,是否可以在本例中使用__slots__?我想我可以通过将 '__slots__' 传递到 type 的第三个参数的字典中来让它工作: class GeocodeResult(ob
我读入了Usage of __slots__?在 Python 中使用 __slots__ 实际上可以节省时间。但是,当我尝试使用 datetime 查找所花费的时间时,结果却相反。 import d
我正在使用 Python 3.7 和 Django。我正在阅读 __slots__ .显然,__slots__ 可用于通过提前列出所有对象属性来优化大量此类对象的内存分配。 class MyClass
我正在编写一个配置卷的存储自动化模块。我没有传递在存储 Controller 上实际创建卷所需的六个或更多参数,而是使用 __slots__ 创建了一个参数类,它被传递到 create 方法中,如下所
我是一名优秀的程序员,十分优秀!