我正在使用类似于此代码的东西:
class BaseClass(object):
def __getattr__(self, attr):
return lambda:'1'
class SubClass(BaseClass):
def foo(self):
suffix = '2'
return super(SubClass, self).foo() + suffix
class SubClass2(SubClass):
def foo(self):
suffix = '3'
return super(SubClass2, self).foo() + suffix
o = SubClass2()
print o.foo()
我希望看到“123”的输出,但我却收到错误 AttributeError: 'super' object has no attribute 'foo'。 Python 甚至没有尝试使用基类的 __getattr__。
如果不修改基类并保持两个 super 调用相似,我无法获得我想要的输出。是否有适合我的合作 super 调用模式?
我知道 super() 以某种方式覆盖 getattr 来做它需要做的事情,但我想问的是是否有任何合理的解决方法允许子类的 __getattr__ 在适当的时候被调用。
最佳答案
啊,这是个好问题!
简而言之,这里发生的是 CPython 内部偶尔需要 他们在进行属性查找时的快捷方式,这种令人惊讶的 行为是后果之一(另一个是提高绩效)。
要准确了解这种情况下发生的情况,我们需要冒险
进入 super 的定义:
http://hg.python.org/cpython/file/c24941251473/Objects/typeobject.c#l6689
特别注意它没有定义
tp_getattr
(又名 __getattr__),但确实定义了 tp_getattro (又名 __getattribute__):
PyTypeObject PySuper_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"super", /* tp_name */
...
0, /* tp_getattr */
...
super_getattro, /* tp_getattro */
...
};
(回想一下 __getattribute__ 每次一个属性被调用
请求,而不是 __getattr__,后者仅在属性被调用时调用
对象上不存在(粗略地说:如果属性不在对象的
__dict__)).
接下来,查看的定义
super_getattro
(又名 super.__getattribute__),我们可以看到实现是
大约:
class super(object):
def __init__(self, obj_type, obj):
self.obj_type = obj_type
self.obj = obj
def __getattribute__(self, attr):
i = self.obj_type.__mro__.find(self.obj_type)
i += 1
while i < len(obj_type.__mro__):
cur_type = self.obj_type.__mro__[i]
cur_dict = cur_type.__dict___
res = cur_dict.get(attr)
if res is not None:
return res
i += 1
return object.__getattribute__(self, attr)
这很明显为什么 super 不能很好地与 __getattr__ 一起玩 —
super 只检查父类中的属性' __dict__!
有趣的是:似乎 pypy(从 2.1.0 开始)的行为方式相同:
$ pypy super.py
Traceback (most recent call last):
File "app_main.py", line 72, in run_toplevel
File "super.py", line 16, in <module>
print o.foo()
File "super.py", line 13, in foo
return super(SubClass2, self).foo() + suffix
File "super.py", line 8, in foo
return super(SubClass, self).foo() + suffix
AttributeError: 'super' object has no attribute 'foo'
关于python:__getattr__ 的协作 super 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18413262/
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的