Python构造函数和__init__

问题:Python构造函数和__init__

为什么构造函数确实称为“构造函数”?它们的目的是什么?它们与类中的方法有何不同?

另外,__init__一个Class中可以有更多人吗?我尝试了以下方法,有人可以解释一下结果吗?

>>> class test:
    def __init__(self):
        print "init 1"
    def __init__(self):
        print "init 2"

>>> s=test()
init 2

最后,是__init__运算符重载器吗?

Why are constructors indeed called “Constructors”? What is their purpose and how are they different from methods in a class?

Also, can there be more that one __init__ in a class? I tried the following, can someone please explain the result?

>>> class test:
    def __init__(self):
        print "init 1"
    def __init__(self):
        print "init 2"

>>> s=test()
init 2

Finally, is __init__ an operator overloader?


回答 0

Python中没有函数重载,这意味着您不能拥有多个具有相同名称但参数不同的函数。

在您的代码示例中,您没有过载 __init__()。发生的是第二个定义将名称重新绑定__init__到新方法,导致第一个方法不可访问。

至于关于构造函数的一般问题,维基百科是一个很好的起点。对于特定于Python的内容,我强烈推荐Python文档

There is no function overloading in Python, meaning that you can’t have multiple functions with the same name but different arguments.

In your code example, you’re not overloading __init__(). What happens is that the second definition rebinds the name __init__ to the new method, rendering the first method inaccessible.

As to your general question about constructors, Wikipedia is a good starting point. For Python-specific stuff, I highly recommend the Python docs.


回答 1

为什么构造函数确实称为“构造函数”?

构造函数(名为__new__)创建并返回该类的新实例。因此,C.__new__类方法是类C 的构造函数

C.__init__创建特定实例后,将在特定实例上调用该实例方法,以对其进行初始化,然后再传递回调用方。因此,该方法是C的新实例的初始化程序

它们与类中的方法有何不同?

官方文档 __init__所述,实例创建后即被调用。其他方法不接受这种治疗。

他们的目的是什么?

构造函数的目的C.__new__是在构造新C实例期间定义自定义行为。

初始化程序的目的是为创建后C.__init__的每个实例定义自定义初始化C

例如,Python允许您执行以下操作:

class Test(object):
    pass

t = Test()

t.x = 10   # here you're building your object t
print t.x

但是,如果您希望每个实例Test的属性都x等于10,则可以将该代码放入其中__init__

class Test(object):
    def __init__(self):
        self.x = 10

t = Test()
print t.x

每个实例方法(在类的特定实例上调用的方法)都会将该实例作为其第一个参数。该论点通常命名为self

诸如构造方法之类的类方法将__new__接收类作为其第一个参数。

现在,如果您想要x属性的自定义值,您要做的就是将该值作为参数传递给__init__

class Test(object):
    def __init__(self, x):
        self.x = x

t = Test(10)
print t.x
z = Test(20)
print t.x

我希望这会帮助您清除一些疑问,并且由于您已经收到其他问题的良好答案,因此我将在这里停止:)

Why are constructors indeed called “Constructors” ?

The constructor (named __new__) creates and returns a new instance of the class. So the C.__new__ class method is the constructor for the class C.

The C.__init__ instance method is called on a specific instance, after it is created, to initialise it before being passed back to the caller. So that method is the initialiser for new instances of C.

How are they different from methods in a class?

As stated in the official documentation __init__ is called after the instance is created. Other methods do not receive this treatment.

What is their purpose?

The purpose of the constructor C.__new__ is to define custom behaviour during construction of a new C instance.

The purpose of the initialiser C.__init__ is to define custom initialisation of each instance of C after it is created.

For example Python allows you to do:

class Test(object):
    pass

t = Test()

t.x = 10   # here you're building your object t
print t.x

But if you want every instance of Test to have an attribute x equal to 10, you can put that code inside __init__:

class Test(object):
    def __init__(self):
        self.x = 10

t = Test()
print t.x

Every instance method (a method called on a specific instance of a class) receives the instance as its first argument. That argument is conventionally named self.

Class methods, such as the constructor __new__, instead receive the class as their first argument.

Now, if you want custom values for the x attribute all you have to do is pass that value as argument to __init__:

class Test(object):
    def __init__(self, x):
        self.x = x

t = Test(10)
print t.x
z = Test(20)
print t.x

I hope this will help you clear some doubts, and since you’ve already received good answers to the other questions I will stop here :)


回答 2

类只是从中创建对象的蓝图。构造函数是每次创建对象时都会运行的一些代码。因此,有两个构造函数是没有意义的。发生的是第二个覆盖了第一个。

通常将它们用作对象的创建变量,如下所示:

>>> class testing:
...     def __init__(self, init_value):
...         self.some_value = init_value

因此,您可以做的是从此类创建一个对象,如下所示:

>>> testobject = testing(5)

然后,testobject将有一个对象some_value,在该示例中该对象将为5。

>>> testobject.some_value
5

但是您不需要像我在示例中那样为每个对象设置值。您也可以这样:

>>> class testing:
...     def __init__(self):
...         self.some_value = 5

那么some_value的值将为5,并且在创建对象时无需设置它。

>>> testobject = testing()
>>> testobject.some_value
5

我的示例中的>>>和…不是您编写的。这就是在pyshell中的外观…

Classes are simply blueprints to create objects from. The constructor is some code that are run every time you create an object. Therefor it does’nt make sense to have two constructors. What happens is that the second over write the first.

What you typically use them for is create variables for that object like this:

>>> class testing:
...     def __init__(self, init_value):
...         self.some_value = init_value

So what you could do then is to create an object from this class like this:

>>> testobject = testing(5)

The testobject will then have an object called some_value that in this sample will be 5.

>>> testobject.some_value
5

But you don’t need to set a value for each object like i did in my sample. You can also do like this:

>>> class testing:
...     def __init__(self):
...         self.some_value = 5

then the value of some_value will be 5 and you don’t have to set it when you create the object.

>>> testobject = testing()
>>> testobject.some_value
5

the >>> and … in my sample is not what you write. It’s how it would look in pyshell…


回答 3

创建新对象时会自动调用coonstructor,从而“构造”该对象。可以具有多个init的原因是因为名称只是python中的引用,并且您可以随时更改每个变量引用的内容(因此可以进行动态类型输入)

def func(): #now func refers to an empty funcion
    pass
...
func=5      #now func refers to the number 5
def func():
    print "something"    #now func refers to a different function

在您的类定义中,它只保留下一个

coonstructors are called automatically when you create a new object, thereby “constructing” the object. The reason you can have more than one init is because names are just references in python, and you are allowed to change what each variable references whenever you want (hence dynamic typing)

def func(): #now func refers to an empty funcion
    pass
...
func=5      #now func refers to the number 5
def func():
    print "something"    #now func refers to a different function

in your class definition, it just keeps the later one


回答 4

Python中没有方法重载的概念。但是您可以通过指定可选参数和关键字参数来达到类似的效果

There is no notion of method overloading in Python. But you can achieve a similar effect by specifying optional and keyword arguments