首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >即使存在属性,getattr()也总是调用现有的__getattr__()吗?

即使存在属性,getattr()也总是调用现有的__getattr__()吗?
EN

Stack Overflow用户
提问于 2015-10-24 16:58:32
回答 2查看 2.2K关注 0票数 2

是真的吗?

我在下一个代码中遇到了困难。我想稍后在execute()调用中调用一些方法。但令人惊讶的是,python在调用getattr(self,...)时调用默认方法getattr(self,...),而不是首先搜索方法__m1和__m2。

代码语言:javascript
复制
class MyApi(object):
    "Class with API."

    def __init__(self):
        self.methods = []


    class Callable(object):
        def __init__(self, obj, name):
            self.obj = obj
            self.name = name            

        def __call__(self, *args, **kwargs):            
            self.obj.methods.append((self.name, args, kwargs,))


    def __m1(self, name):
        print "m1: name is %s" % name
        exit(0)


    def __m2(self, *args, **kwargs):
        print "m2: args is {} and kwargs is {}".format(args, kwargs)
        exit(0)


    def execute(self):
        for meth in self.methods:
            meth_name = '__' + meth[0]          
            print meth_name
            getattr(self, meth_name)(*meth[1], **meth[2]) # it seems to call __getattr__, not existing __m1 and __m2

        self.methods = []

    def __getattr__(self, name):
        return MyApi.Callable(self, name)



api = MyApi()

#import pdb; pdb.set_trace()

api.m1('Serg')
api.m2('John', 'Harrison', **{'key1': 1, 'key2': 2})

api.execute()

讨论的结果.

我们一致认为问题是在两个下划线中隐藏属性__m1__m2

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-10-24 17:06:48

来自文档

当属性查找没有在通常的位置找到属性时调用(即它不是实例属性,也不是自定义的类树中的属性)。..。注意,如果通过正常机制找到该属性,则不会调用__getattr__()

所以不,在正常情况下不应该叫它。

如果内部方法调用__getattr__有问题,则可以始终使用object.__getattr__(self, attr_name)来使用python的默认查找。

如果您确实遇到了这样的问题,您可能会遇到名称残缺 of dunder的问题。如果类属性以_d_ouble _under_scores开头,python将从类的实例以外的任何地方破坏访问的名称。这包括儿童课程!对“私有”方法/属性使用单个下划线,除非您确实需要该功能。

票数 4
EN

Stack Overflow用户

发布于 2015-10-24 17:03:58

不是的。

如果存在属性,则不调用__getattr__

当您想要这样的行为时,必须使用__getattribute__方法。

在我看来,您的问题是(正如MisterMiyagi正确地指出的),方法名为__m1__m2 (顺便说:正确的名称是什么--在一个位置上,您在另一个__m1中称它为m1 --这是不一致的)将被系统破坏。也就是说,系统将它们看作是_<classname>__<methodname>_MyApi__m1。因此,在使用"getattr“时,必须使用损坏的名称。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33320838

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档