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

为什么这是假的?SomeClass.method是SomeClass.method

宗政德宇
2023-03-14
问题内容

以下面的代码为例:

class SomeClass():
    def a_method(self):
        pass

print(SomeClass.a_method is SomeClass.a_method)     # Example 1: False
print(SomeClass.a_method == SomeClass.a_method)     # Example 2: True
print(SomeClass().a_method is SomeClass().a_method) # Example 3: False
print(SomeClass().a_method == SomeClass().a_method) # Example 4: False
  • 示例1:我猜他们是同一对象。每次引用时,Python都会复制该方法吗?
  • 示例2:预期。
  • 示例3:预期,因为它们是不同的对象。
  • 示例4:为什么此输出与示例2不匹配?

问题答案:

范例1:

Someclass.a_method是一种 未绑定的方法 。这些在当今的Python中甚至都不存在,因此请认为这是无用的历史课程。

每次引用时,Python都会复制该方法吗?

是的,或多或少。这是通过描述符协议完成的。

>>> SomeClass.a_method  # unbound method via attribute access
<unbound method SomeClass.a_method>
>>> SomeClass.__dict__['a_method']  # just stored as a function in the class dict
<function __main__.a_method>
>>> SomeClass.__dict__['a_method'].__get__(None, SomeClass)
<unbound method SomeClass.a_method>

最后一行显示了描述符为类上的属性访问而调用的“绑定”操作,但是是手动写出的。在纯Python中,就像这样

class Function(object):
    def __get__(self, obj, objtype=None):
        "Simulate func_descr_get() in Objects/funcobject.c"
        return types.MethodType(self, obj, objtype):

您还可以通过以下方式创建绑定方法:

>>> some_instance = SomeClass()
>>> SomeClass.__dict__['a_method'].__get__(some_instance, SomeClass)
<bound method SomeClass.a_method of <__main__.SomeClass instance at 0xcafef00d>>

范例2:

方法比较是通过方法上的__func____self__属性完成的。在这种情况下,它们是相同的:the__func__是可以从类dict中挖掘出来的相同的老式函数,__self__is是None。因此,尽管这些方法是不同的对象,但它们比较相等。

范例3:

正确。它们是不同的对象,因此不相同。

范例4:

如前所述,比较使用__func____self__属性。结果与示例2不匹配,因为在这种情况下,__self__属性引用的是不同的实例。那些不同的实例之所以不相等,是因为SomeClass实例按身份进行比较,因此这些方法也不相等。

示例1 之外,上述所有内容均适用于该语言的当前版本。在Python中,不再有未绑定方法之类的东西,对象模型中这种不必要的复杂性已被消除。

>>> SomeClass.a_method
<function __main__.SomeClass.a_method(self)>
>>> SomeClass.a_method is SomeClass.__dict__['a_method']
True

现在,Python 2中的“未绑定方法”只是一个普通的旧函数,并且通过属性访问检索的实例与dict类中的对象相同。在Python 2-> Python
3升级中, 示例1的 结果从False变为True



 类似资料:
  • 这是一个简单的程序,生成0到1000之间的两个随机数,然后让用户输入两个数字的和。即使您输入了正确的答案,并且求和与答案匹配,if语句也总是计算为不正确。

  • 当我跑的时候 我在Java中得到错误。为什么?这相当于false==false,这是真的。这不是Java特有的,我在其他语言中也得到了相同的结果。这是因为短路评估吗?似乎左右双方仍会/应该进行比较。

  • 我几天前听说了Docker的事,想过去看看。 但事实上,我不知道这个“容器”的用途是什么? 什么是容器? 它能取代一个专门用于开发的虚拟机吗? 简单地说,在公司中使用Docker的目的是什么?主要的优势?

  • 如果我运行deldeldel(“adel”),它会返回一个,但是,adel的长度是4,这意味着最后一个字符串索引是3,为什么str.substring(4,str.length()没有超出范围?

  • 我正试图找到更快的批量插入方法。 我试图用jdbcTemplate.update(String sql)插入几个批次,其中sql是由StringBuilder构建的,看起来像: 批量大小正好是1000。我插入了将近100批。我用秒表查看了时间,发现了插入时间: 我很高兴,但我想让我的代码更好。 之后,我尝试使用jdbcTemplate.batch更新的方式如下: sql是什么样子的 我很失望!jd

  • 问题内容: 当我调用toString从函数调用中收到的对象时,会得到此信息。我知道对象的类型编码在此字符串中,但是我不知道如何读取它。 这种编码称为什么类型? 问题答案: ;是的名称代表的数组的类。 命名方案记录在: 如果该类对象表示的引用类型不是数组类型,则返回该类的二进制名称,如Java语言规范(§13.1)所指定。 如果此类对象表示原始类型或void,则返回的名称是与原始类型或对应的Java