当前位置: 首页 > 面试题库 >

Python:如何实现__getattr __()?

皇甫飞光
2023-03-14
问题内容

我的班级有一个字典,例如:

class MyClass(object):
    def __init__(self):
        self.data = {'a': 'v1', 'b': 'v2'}

然后,我想在MyClass实例中使用字典的键来访问字典,例如:

ob = MyClass()
v = ob.a   # Here I expect ob.a returns 'v1'

我知道这应该由__getattr__实现,但是我是Python的新手,我并不完全知道如何实现它。


问题答案:
class MyClass(object):

    def __init__(self):
        self.data = {'a': 'v1', 'b': 'v2'}

    def __getattr__(self, attr):
        return self.data[attr]
>>> ob = MyClass()
>>> v = ob.a
>>> v
'v1'

__setattr__不过在实施时要小心,您将需要进行一些修改:

class MyClass(object):

    def __init__(self):
        # prevents infinite recursion from self.data = {'a': 'v1', 'b': 'v2'}
        # as now we have __setattr__, which will call __getattr__ when the line
        # self.data[k] tries to access self.data, won't find it in the instance 
        # dictionary and return self.data[k] will in turn call __getattr__
        # for the same reason and so on.... so we manually set data initially
        super(MyClass, self).__setattr__('data', {'a': 'v1', 'b': 'v2'})

    def __setattr__(self, k, v):
        self.data[k] = v

    def __getattr__(self, k):
        # we don't need a special call to super here because getattr is only 
        # called when an attribute is NOT found in the instance's dictionary
        try:
            return self.data[k]
        except KeyError:
            raise AttributeError
>>> ob = MyClass()
>>> ob.c = 1
>>> ob.c
1

如果您不需要设置属性,只需使用namedtuple例如。

>>> from collections import namedtuple
>>> MyClass = namedtuple("MyClass", ["a", "b"])
>>> ob = MyClass(a=1, b=2)
>>> ob.a
1

如果您想要默认参数,则可以围绕它编写包装类:

class MyClass(namedtuple("MyClass", ["a", "b"])):

    def __new__(cls, a="v1", b="v2"):
        return super(MyClass, cls).__new__(cls, a, b)

或者作为函数看起来更好:

def MyClass(a="v1", b="v2", cls=namedtuple("MyClass", ["a", "b"])):
    return cls(a, b)
>>> ob = MyClass()
>>> ob.a
'v1'


 类似资料:
  • 问题内容: 我见过有人说python 中的对象具有O(1)成员资格检查。如何在内部实现它们以允许这样做?它使用哪种数据结构?该实现还有什么其他含义? 这里的每个答案都非常有启发性,但是我只能接受一个答案,因此,我将选择与原始问题最接近的答案。谢谢你的信息! 问题答案: 实际上,CPython的集合被实现为类似于带有伪值的字典(键是集合的成员)的字典,并且进行了一些优化,可以利用这种缺乏值的方式 因

  • 问题内容: 我想知道python字典如何在后台运行,尤其是动态方面?创建字典时,其初始大小是多少?如果我们用很多元素更新它,我想我们需要扩大哈希表。我想我们需要重新计算散列函数以适应新的更大的散列表的大小,同时又与先前的散列表保持某种逻辑? 如您所见,我不完全了解此结构的内部。 问题答案: (部分)以下答案来自“ 升级Python技能”:检查字典。有关Python哈希表的更多信息,请参见The H

  • 问题内容: 我以前的编程中,代码段仅用于调试目的(记录命令等)。通过使用预处理程序指令,可以完全禁用这些语句以进行生产,如下所示: 做类似的事情的最好方法是什么? 问题答案: 如果只想禁用日志记录方法,请使用该模块。如果日志级别设置为排除调试语句,那么它将非常接近无操作(它仅检查日志级别并返回而不插入日志字符串)。 如果要在特定条件下以字节码编译时实际删除代码块,则唯一的选择是相当神秘的全局变量。

  • 本文向大家介绍python如何实现图片压缩,包括了python如何实现图片压缩的使用技巧和注意事项,需要的朋友参考一下 本工具是通过将图片上传到第三方网站tinypng,进行压缩后下载,覆盖本地图片,tinypng是一个强大的图片处理网站,目前最可靠的无损压缩网站。 代码如下: 改进版 优化点: 1.遍历完成本地文件夹再去上传网站 2.所有图片压缩完成再去下载 3.启动多线程下载 4.设定时间为加

  • 问题内容: 如何实现与C#代码等效的Python? 这是一个好主意吗??请在您的答案中举例说明。 问题答案: 正如其他人在这里提到的: 在Python中不需要接口。这是因为Python具有适当的多重继承,还具有鸭式输入法,这意味着 必须 在Java中具有接口的地方,而不必在Python中具有接口。 也就是说,接口还有多种用途。其中一些被Python 2.6中引入的Pythons抽象基类覆盖。如果您

  • 问题内容: 我想知道Python 3中的新super是如何实现的。 我做了一个小例子之后,这个问题就浮现在脑海中,我得到了一个奇怪的错误。我正在使用Pyutilib组件体系结构(PCA),并且已经制作了自定义元类来驱动另一个类的创建: 我收到以下错误: 我wonderign究竟超(一样),它引发的错误,而所有的,并存在。另外的“老方法”-正在工作。 问题答案: 如何执行?这是python3.3的代