实现课程 - 有和没有括号之间的区别

时间:2021-08-31 20:27:28

Taking back Python after a long time and would like to refresh some concepts, I hope this question is not a bad one.

经过很长一段时间收回Python并希望刷新一些概念,我希望这个问题不错。

Say I have a very simple class like the following:

假设我有一个非常简单的类,如下所示:

class myClass:
    def __init__(self): 
        self.myProp = 2

If I instantiate using the brackets, everything works as I expect:

如果我使用括号实例化,一切都按预期工作:

>>> a = myClass()
>>> a.myProp
2

However, if I don't use the brackets on the two lines above, i.e.:

但是,如果我不使用上面两行的括号,即:

>>> a = myClass

I get the following error:

我收到以下错误:

>>> a.myProp
Traceback (most recent call last):
File "<pyshell#45>", line 1, in <module>
a.myProp
AttributeError: class myClass has no attribute 'myProp'

If I print the object,

如果我打印对象,

>>> a = myClass
>>> a

I get

我明白了

<class __main__.myClass at 0x0275C538>

It seems that a is an instance of the class, but somehow is not initialized. In other languages, I would expect a compile error if trying to cast a class instance into an object without initalizing it (e.g. in C#, myClass a = new myClass(); would work fine but myClass a = new myClass; would return a compile error).

似乎a是类的一个实例,但不知何故没有初始化。在其他语言中,如果尝试将类实例转换为对象而不进行初始化(例如在C#中,myClass a = new myClass();我会工作正常但是myClass a = new myClass;我将返回编译错误)。

So my question is: what is, technically speaking, the object a = myClass without brackets?

所以我的问题是:从技术上讲,对象a = myClass没有括号?

3 个解决方案

#1


6  

a is the class itself -- In python, classes are first class objects1. You can pass them around as parameters, alias them to different names (as you've done in your example) and then you can instances from any reference that you have in the current namespace.

a是类本身 - 在python中,类是第一类对象1。您可以将它们作为参数传递,将它们别名为不同的名称(正如您在示例中所做的那样),然后您可以使用当前命名空间中的任何引用实例。

a = myClass  # a and myClass identical at this point.  The interpretter won't care which you use.
a_instance = a()  # instance of myClass

def make_instance(cls):
    return cls()

another_instance = make_instance(a)
yet_another_instance = make_instance(myClass)

You see, python doesn't have any "compile time checking" because really -- there is no compile time. Python code gets interpreted at runtime. True, you can have SyntaxErrors pop up at when you import something, but that is still during runtime.

你看,python没有任何“编译时检查”因为真的 - 没有编译时间。 Python代码在运行时被解释。是的,您可以在导入内容时弹出SyntaxErrors,但这仍然在运行时期间。

1No pun intended

1没有双关语意图

#2


4  

It's a reference to the class itself, rather than a reference to an instance of the class. Note the difference:

它是对类本身的引用,而不是对类实例的引用。注意区别:

>>> a = myClass
>>> a
<class __main__.myClass at 0x10cd1de20>
>>> b = myClass()
>>> b
<__main__.myClass instance at 0x10cd8efc8>

#3


3  

Everything in Python is an object and thus an instance of a class, including classes. There is nothing special about manipulating classes or passing them around as variables. Thus your variables a and MyClass, which refer to the same object, are just the object that is MyClass.

Python中的所有内容都是一个对象,因此是一个类的实例,包括类。操作类或将它们作为变量传递没有什么特别之处。因此,引用同一对象的变量a和MyClass只是MyClass的对象。

>>> class R: pass # In Python 2, you would need class R(object): pass
>>> r = R()

Now we have two variables, R and r. r is an instance of class R. The trick here is that R is an instance of class type, which is why we call R a class. Both r and R are instances of object, which is why we call both of them objects. And R is a subclass of class object because R is a class.

现在我们有两个变量,R和r。 r是类R的一个实例。这里的技巧是R是类类型的实例,这就是我们称R为类的原因。 r和R都是对象的实例,这就是我们将它们都称为对象的原因。 R是类对象的子类,因为R是一个类。

>>> isinstance(R, type)
True
>>> isinstance(r, R)
True
>>> issubclass(R, object)
True
>>> isinstance(r, object)
True
>>> isinstance(type, object)
True
>>> isinstance(type, type)
True

Every Python object is an instance of object and every Python class is a subclass of object and every Python class is an instance of type.

每个Python对象都是一个对象的实例,每个Python类都是对象的子类,每个Python类都是一个类型的实例。

Note that what I'm saying is true in Python 3 and for Python 2 "new style" classes. Do not concern yourself with Python old-style classes.

请注意,我所说的在Python 3和Python 2“新风格”类中都是正确的。不要关心Python旧式类。

#1


6  

a is the class itself -- In python, classes are first class objects1. You can pass them around as parameters, alias them to different names (as you've done in your example) and then you can instances from any reference that you have in the current namespace.

a是类本身 - 在python中,类是第一类对象1。您可以将它们作为参数传递,将它们别名为不同的名称(正如您在示例中所做的那样),然后您可以使用当前命名空间中的任何引用实例。

a = myClass  # a and myClass identical at this point.  The interpretter won't care which you use.
a_instance = a()  # instance of myClass

def make_instance(cls):
    return cls()

another_instance = make_instance(a)
yet_another_instance = make_instance(myClass)

You see, python doesn't have any "compile time checking" because really -- there is no compile time. Python code gets interpreted at runtime. True, you can have SyntaxErrors pop up at when you import something, but that is still during runtime.

你看,python没有任何“编译时检查”因为真的 - 没有编译时间。 Python代码在运行时被解释。是的,您可以在导入内容时弹出SyntaxErrors,但这仍然在运行时期间。

1No pun intended

1没有双关语意图

#2


4  

It's a reference to the class itself, rather than a reference to an instance of the class. Note the difference:

它是对类本身的引用,而不是对类实例的引用。注意区别:

>>> a = myClass
>>> a
<class __main__.myClass at 0x10cd1de20>
>>> b = myClass()
>>> b
<__main__.myClass instance at 0x10cd8efc8>

#3


3  

Everything in Python is an object and thus an instance of a class, including classes. There is nothing special about manipulating classes or passing them around as variables. Thus your variables a and MyClass, which refer to the same object, are just the object that is MyClass.

Python中的所有内容都是一个对象,因此是一个类的实例,包括类。操作类或将它们作为变量传递没有什么特别之处。因此,引用同一对象的变量a和MyClass只是MyClass的对象。

>>> class R: pass # In Python 2, you would need class R(object): pass
>>> r = R()

Now we have two variables, R and r. r is an instance of class R. The trick here is that R is an instance of class type, which is why we call R a class. Both r and R are instances of object, which is why we call both of them objects. And R is a subclass of class object because R is a class.

现在我们有两个变量,R和r。 r是类R的一个实例。这里的技巧是R是类类型的实例,这就是我们称R为类的原因。 r和R都是对象的实例,这就是我们将它们都称为对象的原因。 R是类对象的子类,因为R是一个类。

>>> isinstance(R, type)
True
>>> isinstance(r, R)
True
>>> issubclass(R, object)
True
>>> isinstance(r, object)
True
>>> isinstance(type, object)
True
>>> isinstance(type, type)
True

Every Python object is an instance of object and every Python class is a subclass of object and every Python class is an instance of type.

每个Python对象都是一个对象的实例,每个Python类都是对象的子类,每个Python类都是一个类型的实例。

Note that what I'm saying is true in Python 3 and for Python 2 "new style" classes. Do not concern yourself with Python old-style classes.

请注意,我所说的在Python 3和Python 2“新风格”类中都是正确的。不要关心Python旧式类。