- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
问题是指哪个更适合用于哪个用例,而不是技术背景。
在 python 中,您可以通过属性、描述符或魔术方法来控制属性的访问。在哪个用例中哪个是最pythonic的?它们似乎都具有相同的效果(请参见下面的示例)。
我正在寻找这样的答案:
示例
用例是可能无法在 __init__
方法中设置的属性,例如,因为该对象尚未出现在数据库中,但稍后会出现。每次访问属性时,都应尝试设置并返回。
作为在 Python shell 中使用复制和粘贴的示例,有一个类只想在第二次被要求时显示其属性。那么,哪一种是最好的方法,或者在不同的情况下,其中一种更可取?以下是实现它的三种方法:
具有属性::
class ContactBook(object):
intents = 0
def __init__(self):
self.__first_person = None
def get_first_person(self):
ContactBook.intents += 1
if self.__first_person is None:
if ContactBook.intents > 1:
value = 'Mr. First'
self.__first_person = value
else:
return None
return self.__first_person
def set_first_person(self, value):
self.__first_person = value
first_person = property(get_first_person, set_first_person)
使用 __getattribute__
::
class ContactBook(object):
intents = 0
def __init__(self):
self.first_person = None
def __getattribute__(self, name):
if name == 'first_person' \
and object.__getattribute__(self, name) is None:
ContactBook.intents += 1
if ContactBook.intents > 1:
value = 'Mr. First'
self.first_person = value
else:
value = None
else:
value = object.__getattribute__(self, name)
return value
描述符::
class FirstPerson(object):
def __init__(self, value=None):
self.value = None
def __get__(self, instance, owner):
if self.value is None:
ContactBook.intents += 1
if ContactBook.intents > 1:
self.value = 'Mr. First'
else:
return None
return self.value
class ContactBook(object):
intents = 0
first_person = FirstPerson()
它的每一个都有这种行为::
book = ContactBook()
print(book.first_person)
# >>None
print(book.first_person)
# >>Mr. First
最佳答案
基本上,尽可能使用最简单的。粗略地说,复杂性/重型性的顺序是:常规属性,property
, __getattr__
, __getattribute__
/描述符。 (__getattribute__
和自定义描述符都是您可能不需要经常做的事情。)这引出了一些简单的经验法则:
property
如果普通属性会起作用。property
不写你自己的描述符将工作。__getattr__
如果 property
将工作。__getattribute__
如果__getattr__
将工作。更具体地说:使用属性来自定义对一个或一小组属性的处理;使用 __getattr__
定制所有属性的处理,或者除了一小部分之外的所有属性;使用 __getattribute__
如果你希望使用 __getattr__
但它不太管用;如果您正在做一些非常复杂的事情,请编写您自己的描述符类。
您使用 property
当您有一个或一小组属性时,您想要 Hook 其获取/设置。也就是说,你想要像 obj.prop
这样的东西和 obj.prop = 2
secret 调用您编写的函数来自定义发生的情况。
您将使用 __getattr__
当您想要对如此多的属性执行此操作时,您实际上并不想单独定义它们,而是希望将整个属性访问过程作为一个整体进行自定义。换句话说,而不是 Hook obj.prop1
, 和 obj.prop2
等等,你有这么多,你希望能够 Hook obj.<anything>
,并进行一般处理。
然而,__getattr__
仍然不会让您覆盖真正存在的属性所发生的情况,它只是让您 Hook 对任何使用属性的全面处理,否则会引发 AttributeError。使用 __getattribute__
让您可以处理一切,甚至可以正常工作而不会弄乱 __getattribute__
的普通属性.因此,使用 __getattribute__
有可能破坏相当基本的行为,因此只有在考虑使用 __getattr__
时才应使用它这还不够。它还会对性能产生显着影响。例如,您可能需要使用 __getattribute__
如果您正在包装一个定义某些属性的类,并且您希望能够以自定义方式包装这些属性,以便它们在某些情况下照常工作,但在其他情况下获得自定义行为。
最后,我想说编写您自己的描述符是一项相当高级的任务。 property
是一个描述符,对于大约 95% 的情况,它是您唯一需要的。 here 给出了一个很好的简单示例,说明您为什么要编写自己的描述符: 基本上,如果你不得不写几个 property
,你可能会这样做具有相似行为;描述符可让您分解出常见行为以避免代码重复。例如,自定义描述符用于驱动 Django 和 SQLAlchemy 等系统。如果您发现自己正在编写那种复杂程度的东西,您可能需要编写一个自定义描述符。
在您的示例中,property
将是最好的选择。如果你正在做 if name == 'somespecificname'
,它通常(不总是)是一个危险信号。里面__getattribute__
.如果您只需要专门处理一个特定的名称,您可能可以做到这一点,而不必屈服于 __getattribute__
的级别。 .同样,如果你为它的 __get__
编写所有描述符,那么编写你自己的描述符也没有意义。是您可以在属性的 getter 方法中编写的内容。
关于python - 属性与描述符与 __getattribute__ 的用例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22616559/
来自descriptor文档: A descriptor can be called directly by its method name. For example, d.__get__(obj).
概要 本人python理论知识远达不到传授级别,写文章主要目的是自我总结,并不能照顾所有人,请见谅,文章结尾贴有相关链接可以作为补充 全文分为三个部分装饰器理论知识、装饰器应用、装饰器延申
我正在查看 python 的描述 rune 档 here ,让我思考的陈述是: 对于物体,机械在 object.__getattribute__()转换 b.x进入 type(b).__dict__[
if((fd = creat(file_name,O_RDWR|S_IRWXU|S_IRWXG|S_IRWXO)) < 0){ perror("Create failed!");
长话短说Python 2.7.5,当使用描述符作为装饰器时,有没有办法传入参数(给 __init__ 方法)?或者如何使用带参数的方法装饰器 ( as here ) 访问类实例的属性? -- 我认为这
我试着用谷歌搜索一些关于它的东西。为什么非数据描述符适用于旧式类? 文档说他们不应该: “Note that descriptors are only invoked for new style ob
我升级到使用嵌入式 maven 3 的 netbeans 7。我有一个项目,其中包含许多模块和包含其他模块的模块。我的其他不依赖于内部项目的子模块可以在相同的配置下正常工作。在这种情况下,spring
我正在关注http://scikit-image.org/docs/0.11.x/auto_examples/plot_daisy.html ,但是不太清楚 desc[0],desc[1] 和 des
我有一个要求,其中有一个全局 FILE指针/描述符。其中一个函数将从该指针/描述符中读取。与FILE指针/描述符相关联的内部指针前进。此函数返回后,我想从同一个 FILE 指针/描述符中读取数据,并与
我正在编写一些描述符来封装数据验证,并想为它们编写测试。 我想知道是否应该通过在我的测试中创建描述符实例然后显式调用 __get__ 或 __set__ 方法来测试它们。 或者我应该在我的测试文件中创
我有这个 python 描述符: # Date Descriptor class DateAttribute(): def __init__(self, value=None):
分割: @font-face { font-family: 'RobotoLight'; src: url('../font/jura-demibold.eot'); src: url('../fon
我正在编写一个配置卷的存储自动化模块。我没有传递在存储 Controller 上实际创建卷所需的六个或更多参数,而是使用 __slots__ 创建了一个参数类,它被传递到 create 方法中,如下所
在我的应用程序中,我必须使用静态摄像头跟踪大学讲座中的讲师。目前我正在使用 Emgu CV 的默认 GPUHOGDescriptor,如果讲师的整个 body 都可见,它会很好用。在讲师站在 tabl
大家好,我正在使用 opencv3 和 contrib。问题是我想计算给定像素的筛选描述符(不使用检测到的关键点)。 我正在尝试用给定的像素构建一个关键点向量。但是,要创建关键点,除了像素位置外,我还
我正在使用 OpenCV 中的 HOGDescriptor 类进行对象检测。在我看来,该实现仅使用无符号渐变,因此无法区分亮->暗和暗->亮过渡,这是我真正需要的功能。有谁知道使用有符号梯度的 HOG
我目前正在使用 OpenCV 的 ORB 特征提取器,我确实注意到 ORB 描述符的存储方式很奇怪(至少对我来说是这样)(它基本上是一个 BRIEF-32,带有与我的问题无关的修改) .正如你们中的一
我想知道,在 MATLAB 中是否有针对“汽车”之类的对象而非人类的 HOG 描述符的任何实现? 但万一,只有人类,你能指导我找到那个代码,并给我一些提示,以改进代码以用于“汽车或摩托车等物体” 最佳
我正在尝试更好地理解描述符。 我不明白为什么在 foo 方法中描述符 __get__ 方法未被调用。 据我了解描述符 __get__ 当我通过点运算符访问对象属性或使用 __getattribute_
我想要一个类似于这个(无效)的结构: const uint8_t uArray[] = { uint8_t(sizeof(uArray)), 1, 2, 3 }; 并且 uArray[0] 应该是 4
我是一名优秀的程序员,十分优秀!