检查 self.__class__ 的目的是什么?- Python

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20599375/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 20:49:11  来源:igfitidea点击:

What is the purpose of checking self.__class__ ? - python

pythonclassoopinterfaceself

提问by alvas

What is the purpose of checking self.__class__? I've found some code that creates an abstract interface class and then checks whether its self.__class__is itself, e.g.

检查的目的是self.__class__什么?我发现了一些创建抽象接口类的代码,然后检查它是否self.__class__是它本身,例如

class abstract1 (object):
  def __init__(self):
    if self.__class__ == abstract1: 
      raise NotImplementedError("Interfaces can't be instantiated")

What is the purpose of that? Is it to check whether the class is a type of itself?

这样做的目的是什么?是检查类是否是自身的类型?

The code is from NLTK's http://nltk.googlecode.com/svn/trunk/doc/api/nltk.probability-pysrc.html#ProbDistI

代码来自 NLTK 的http://nltk.googlecode.com/svn/trunk/doc/api/nltk.probability-pysrc.html#ProbDistI

采纳答案by Martijn Pieters

self.__class__is a reference to the typeof the current instance.

self.__class__是对当前实例类型的引用。

For instances of abstract1, that'd be the abstract1class itself, which is what you don't want with an abstract class. Abstract classes are only meant to be subclassed, not to create instances directly:

对于 的实例abstract1,那将是abstract1本身,这是抽象类所不希望的。抽象类仅用于子类化,而不是直接创建实例:

>>> abstract1()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in __init__
NotImplementedError: Interfaces can't be instantiated

For an instance of a subclassof abstract1, self.__class__would be a reference to the specific subclass:

对于一个实例子类abstract1self.__class__是将特定的子类的引用:

>>> class Foo(abstract1): pass
... 
>>> f = Foo()
>>> f.__class__
<class '__main__.Foo'>
>>> f.__class__ is Foo
True

Throwing an exception here is like using an assertstatement elsewhere in your code, it protects you from making silly mistakes.

在这里抛出异常就像assert在代码的其他地方使用语句一样,它可以防止您犯愚蠢的错误。

Note that the pythonicway to test for the type of an instance is to use the type()functioninstead, together with an identitytest with the isoperator:

请注意,pythonic测试实例类型的方法是使用该type()函数,以及带有运算符的身份测试is

class abstract1(object):
    def __init__(self):
        if type(self) is abstract1: 
            raise NotImplementedError("Interfaces can't be instantiated")

type()should be preferred over self.__class__because the latter can be shadowed by a class attribute.

type()应该优先考虑,self.__class__因为后者可以被类属性遮蔽

There is little point in using an equality test here as for custom classes, __eq__is basically implemented as an identity test anyway.

对于自定义类,在这里使用相等测试没有什么意义,__eq__无论如何基本上都是作为身份测试实现的。

Python also includes a standard library to define abstract base classes, called abc. It lets you mark methods and properties as abstract and will refuse to create instances of any subclass that has not yet re-defined those names.

Python 还包含一个标准库来定义抽象基类,称为abc. 它允许您将方法和属性标记为抽象,并拒绝创建尚未重新定义这些名称的任何子类的实例。

回答by Andrew Gorcester

The code that you posted there is a no-op; self.__class__ == c1is not part of a conditional so the boolean is evaluated but nothing is done with the result.

您在那里发布的代码没有操作;self.__class__ == c1不是条件的一部分,因此对布尔值进行评估,但对结果不做任何处理。

You could try to make an abstract base class that checks to see if self.__class__is equal to the abstract class as opposed to a hypothetical child (via an if statement), in order to prevent the instantiation of the abstract base class itself due to developer mistake.

您可以尝试创建一个抽象基类来检查是否self.__class__等于抽象类而不是假设的子类(通过 if 语句),以防止由于开发人员错误而导致抽象基类本身的实例化。

回答by Peter Westlake

The clues are in the name of the class, "abstract1", and in the error. This is intended to be an abstract class, meaning one that is intended to be subclassed. Each subclass will provide its own behaviour. The abstract class itself serves to document the interface, i.e. the methods and arguments that classes implementing the interface are expected to have. It is not meant to be instantiated itself, and the test is used to tell whether we are in the class itself or a subclass.

线索在类名“abstract1”和错误中。这旨在成为一个抽象类,这意味着一个旨在被子类化的类。每个子类将提供自己的行为。抽象类本身用于记录接口,即实现接口的类应该具有的方法和参数。它并不意味着自己被实例化,测试用于判断我们是在类本身还是子类中。

See the section on Abstract Classes in this articleby Julien Danjou.

请参阅Julien Danjou这篇文章中有关抽象类的部分。

回答by MxLDevs

What is the purpose of that? Is it to check whether the class is a type of itself?

这样做的目的是什么?是检查类是否是自身的类型?

Yes, if you try to construct an object of type Abstract1it'll throw that exception telling you that you're not allowed to do so.

是的,如果您尝试构造一个类型的对象,Abstract1它会抛出该异常,告诉您不允许这样做。

回答by prosti

In Python 3 either using type()to check for the type or __class__will return the same result.

在 Python 3 中,要么type()用于检查类型,要么__class__将返回相同的结果。

class C:pass
ci=C()
print(type(ci)) #<class '__main__.C'>
print(ci.__class__) #<class '__main__.C'>


I recently checked the implementationfor the @dataclassdecorator (Raymond Hettinger is directly involved into that project), and they are using __class__to refer to the type.

我最近检查落实@dataclass装饰(雷蒙德赫廷杰直接参与到该项目中),以及他们使用__class__来指代的类型。

So it is not wrong to use __class__:)

所以使用没有错__class__:)