Python __init__和self他们做了什么?

时间:2009-03-09 05:09:51

标签: python oop

我正在学习Python编程语言,而且我遇到了一些我并不完全理解的东西。

在类似的方法中:

def method(self, blah):
    def __init__(?):
        ....
    ....

self做什么?这是什么意思?这是强制性的吗?

__init__方法有什么作用?为什么有必要? (等)

我认为它们可能是OOP结构,但我不太了解。

19 个答案:

答案 0 :(得分:517)

在此代码中:

class A(object):
    def __init__(self):
        self.x = 'Hello'

    def method_a(self, foo):
        print self.x + ' ' + foo

... self变量表示对象本身的实例。大多数面向对象的语言都将此作为隐藏参数传递给对象上定义的方法; Python没有。你必须明确声明它。当您创建A类的实例并调用其方法时,它将自动传递,如...

a = A()               # We do not pass any argument to the __init__ method
a.method_a('Sailor!') # We only pass a single argument

__init__方法大致代表Python中的构造函数。当您调用A()时,Python会为您创建一个对象,并将其作为第一个参数传递给__init__方法。任何其他参数(例如A(24, 'Hello'))也将作为参数传递 - 在这种情况下会引发异常,因为构造函数不期望它们。

答案 1 :(得分:214)

是的,你是对的,这些都是oop结构。

__init__是类的构造函数。 self参数引用对象的实例(如C ++中的this)。

class Point:
    def __init__(self, x, y):
        self._x = x
        self._y = y

在分配对象的内存时调用__init__方法:

x = Point(1,2)

如果要使用对象保留值,则必须在对象的方法中使用self参数。例如,如果您实现这样的__init__方法:

class Point:
    def __init__(self, x, y):
        _x = x
        _y = y

您的xy参数将存储在堆栈中的变量中,并在init方法超出范围时被丢弃。将这些变量设置为self._xself._y会将这些变量设置为Point对象的成员(可在对象的生命周期内访问)。

答案 2 :(得分:167)

一个简短的说明性例子

希望它可能会有所帮助,这里有一个简单的例子我用来理解在类中声明的变量和在__init__函数内声明的变量之间的区别:

class MyClass(object):
     i = 123
     def __init__(self):
         self.i = 345

a = MyClass()
print a.i
345
print MyClass.i
123

答案 3 :(得分:38)

简而言之:

  1. self正如它所暗示的那样,指的是本身 - 调用该方法的对象。也就是说,如果你有N个对象调用该方法,那么self.a将为每个N个对象引用一个单独的变量实例。想象一下,每个对象的变量a的N个副本
  2. __init__是其他OOP语言(如C ++ / Java)中的构造函数。基本思想是它是一个特殊的方法,当创建该类的对象时会自动调用该方法

答案 4 :(得分:25)

__init__确实像构造函数一样。如果您希望它们表现为非静态方法,则需要将“self”作为第一个参数传递给任何类函数。 “self”是您班级的实例变量。

答案 5 :(得分:23)

试试这段代码。希望它能帮助像我这样的许多C程序员学习Py。

#! /usr/bin/python2

class Person:

    '''Doc - Inside Class '''

    def __init__(self, name):
        '''Doc - __init__ Constructor'''
        self.n_name = name        

    def show(self, n1, n2):
        '''Doc - Inside Show'''
        print self.n_name
        print 'Sum = ', (n1 + n2)

    def __del__(self):
        print 'Destructor Deleting object - ', self.n_name

p=Person('Jay')
p.show(2, 3)
print p.__doc__
print p.__init__.__doc__
print p.show.__doc__

输出:

Jay

Sum = 5

Doc - Inside Class

Doc - __init__ Constructor

Doc - Inside Show

Destructor Deleting object - Jay

答案 6 :(得分:21)

我自己也遇到了麻烦。即使在这里阅读了答案。

要正确理解您需要了解自己的__init__方法。

自我参数

__init__方法接受的参数是:

def __init__(self, arg1, arg2):

但我们实际上只传递了两个参数:

instance = OurClass('arg1', 'arg2')

额外的争论来自哪里?

当我们访问对象的属性时,我们通过名称(或通过引用)来访问它们。这里的实例是对我们新对象的引用。我们使用instance.printargs访问实例对象的printargs方法。

为了从__init__方法中访问对象属性,我们需要对该对象的引用。

每当调用一个方法时,都会将对主对象的引用作为第一个参数传递。 按照惯例,您总是将第一个参数调用到方法self。 / p>

这意味着我们可以使用__init__方法:

self.arg1 = arg1
self.arg2 = arg2

我们在这里设置对象的属性。 您可以通过执行以下操作来验证这一点:

instance = OurClass('arg1', 'arg2')
print instance.arg1
arg1
像这样的

值称为对象属性。 此处__init__方法设置实例的arg1和arg2属性。

来源:http://www.voidspace.org.uk/python/articles/OOP.shtml#the-init-method

答案 7 :(得分:16)

请注意self实际上可以是任何有效的python标识符。例如,我们可以轻易地写出来自Chris B的例子:

class A(object):
    def __init__(foo):
        foo.x = 'Hello'

    def method_a(bar, foo):
        print bar.x + ' ' + foo

它会完全一样。但是建议使用self,因为其他pythoners会更容易识别它。

答案 8 :(得分:16)

类对象支持两种操作:属性引用和实例化

属性引用 使用Python中所有属性引用使用的标准语法:obj.name。有效的属性名称是创建类对象时类的命名空间中的所有名称。所以,如果类定义看起来像这样:

class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
        return 'hello world'

然后MyClass.iMyClass.f是有效的属性引用,分别返回一个整数和一个函数对象。也可以为类属性分配,因此您可以通过分配更改MyClass.i的值。 __doc__也是一个有效的属性,返回属于该类的docstring:"一个简单的示例类"。

类实例化 使用函数表示法。只是假装类对象是一个无参数函数,它返回一个新的类实例。例如:

x = MyClass()

实例化操作(“调用”类对象)创建一个空对象。许多类喜欢创建具有针对特定初始状态定制的实例的对象。因此,类可以定义名为__init__()的特殊方法,如下所示:

def __init__(self):
    self.data = []

当类定义__init__()方法时,类实例化会自动为新创建的类实例调用__init__()。因此,在此示例中,可以通过以下方式获取新的初始化实例:

x = MyClass()

当然,__init__()方法可能具有更大灵活性的参数。在这种情况下,给予类实例化运算符的参数将传递给__init__()。例如,

class Complex:
    def __init__(self, realpart, imagpart):
        self.r = realpart
        self.i = imagpart

x = Complex(3.0, -4.5)
x.r, x.i

取自最终帮助我的官方documentation

这是我的例子

class Bill():
    def __init__(self,apples,figs,dates):
        self.apples = apples
        self.figs = figs
        self.dates = dates
        self.bill = apples + figs + dates
        print ("Buy",self.apples,"apples", self.figs,"figs 
                and",self.dates,"dates. 
                Total fruitty bill is",self.bill," pieces of fruit :)")

创建类Bill的实例时:

purchase = Bill(5,6,7)

你得到:

> Buy 5 apples 6 figs and 7 dates. Total fruitty bill is 18  pieces of
> fruit :)

答案 9 :(得分:14)

基本上,在同一个类中的多个函数中使用变量时,需要使用'self'关键字。至于 init ,它用于设置默认值,不会调用该类中的其他函数。

答案 10 :(得分:14)

  1. __init__ 基本上是一个功能,它将“初始化” / “激活”特定类的属性对象,一旦创建并匹配到相应的类..
  2. self 表示将继承这些属性的对象。

答案 11 :(得分:12)

'self'是对类实例的引用

class foo:
    def bar(self):
            print "hi"

现在我们可以创建一个foo实例并在其上调用方法,在这种情况下,Python会添加self参数:

f = foo()
f.bar()

但是如果方法调用不在类的实例的上下文中,它也可以传入,下面的代码做同样的事情

f = foo()
foo.bar(f)

有趣的是,变量名'self'只是一个约定。以下定义将完全相同..已经说过非常强大的约定应该遵循总是,但它确实说明了语言的灵活性< / p>

class foo:
    def bar(s):
            print "hi"

答案 12 :(得分:8)

# Source: Class and Instance Variables
# https://docs.python.org/2/tutorial/classes.html#class-and-instance-variables

class MyClass(object):
    # class variable
    my_CLS_var = 10

    # sets "init'ial" state to objects/instances, use self argument
    def __init__(self):
        # self usage => instance variable (per object)
        self.my_OBJ_var = 15

        # also possible, class name is used => init class variable
        MyClass.my_CLS_var = 20


def run_example_func():
    # PRINTS    10    (class variable)
    print MyClass.my_CLS_var

    # executes __init__ for obj1 instance
    # NOTE: __init__ changes class variable above
    obj1 = MyClass()

    # PRINTS    15    (instance variable)
    print obj1.my_OBJ_var

    # PRINTS    20    (class variable, changed value)
    print MyClass.my_CLS_var


run_example_func()

答案 13 :(得分:7)

在此代码中:

class Cat:
    def __init__(self, name):
        self.name = name
    def info(self):
        print 'I am a cat and I am called', self.name

此处__init__充当类的构造函数,并且在实例化对象时,将调用此函数。 self表示实例化对象。

c = Cat('Kitty')
c.info()

以上陈述的结果如下:

I am a cat and I am called Kitty

答案 14 :(得分:7)

只是问题的演示。

class MyClass:

    def __init__(self):
        print('__init__ is the constructor for a class')

    def __del__(self):
        print('__del__ is the destructor for a class')

    def __enter__(self):
        print('__enter__ is for context manager')
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        print('__exit__ is for context manager')

    def greeting(self):
        print('hello python')


if __name__ == '__main__':
    with MyClass() as mycls:
        mycls.greeting()
$ python3 class.objects_instantiation.py
__init__ is the constructor for a class
__enter__ is for context manager
hello python
__exit__ is for context manager
__del__ is the destructor for a class

答案 15 :(得分:5)

  

Python __init__self他们做了什么?

     

self做什么?这是什么意思?这是强制性的吗?

     

__init__方法有什么作用?为什么有必要? (等)

给出的示例不正确,所以让我根据它创建一个正确的示例:

class SomeObject(object):

    def __init__(self, blah):
        self.blah = blah

    def method(self):
        return self.blah 

当我们创建对象的实例时,调用__init__来在创建对象后自定义对象。也就是说,当我们在SomeObject下面调用'blah'时(可能是任何内容),它会作为参数传递给__init__函数blah

an_object = SomeObject('blah')

self参数是SomeObject的实例,将分配给an_object

稍后,我们可能想要在此对象上调用一个方法:

an_object.method()

执行虚线查找,即an_object.method,将实例绑定到函数的实例,并且方法(如上所述)现在是一个“绑定”方法 - 这意味着我们不需要显式地将实例传递给方法调用。

方法调用获取实例,因为它绑定在虚线查找上,并且在调用时,执行它编程执行的任何代码。

按惯例,隐式传递的self参数称为self。我们可以使用任何其他合法的Python名称,但如果您将其更改为其他内容,则可能会受到其他Python程序员的玷污和羽化。

__init__是一种特殊方法documented in the Python datamodel documentation。在创建实例后立即调用它(通常通过__new__ - 尽管除非您是子类化不可变数据类型,否则不需要__new__

答案 16 :(得分:4)

  

自我做什么?什么是意味着?是强制性

每个类方法的第一个参数,包括init,始终是对clas 的当前实例的引用。按照惯例,这个参数总是命名为self。在init方法中,self指的是新创建的对象;在其他类方法中,它指的是调用其方法的实例。

Python 不会强迫您使用&#34; self &#34;。你可以给它任何你想要的名字。但请记住,方法定义中的第一个参数是对object的引用.Python为您添加self参数到列表中;调用方法时不需要包含它。 如果您没有在init方法中提供self,那么您将收到错误

TypeError: __init___() takes no arguments (1 given)
  

init 方法有什么作用?为什么有必要? (等)

init初始化的简称。它是一个构造函数,当你创建类的实例时会被调用,而则没有必要。但通常我们的做法是编写init方法来设置对象的默认状态。如果您不想最初设置对象的任何状态,那么您不需要编写此方法。

答案 17 :(得分:3)

在这里,这个人写得非常简单:https://www.jeffknupp.com/blog/2014/06/18/improve-your-python-python-classes-and-object-oriented-programming/

阅读以上链接作为对此的参考:

  

self?那么所有客户的自我参数是什么呢?   方法?它是什么?为什么,这是实例,当然!换一个   方式,像撤回这样的方法定义了撤销的指令   来自某个抽象客户账户的钱。调用   jeff.withdraw(100.0)将这些指令用于jeff   实例

     

所以,当我们说退出(自我,金额)时,我们说,“这是怎么回事   你从一个客户对象(我们称之为自我)和   美元数字(我们称之为金额)。自我是实例   正在呼叫退出的客户。那不是我制作的   类比,或者。 jeff.withdraw(100.0)只是简写   Customer.withdraw(jeff,100.0),这是完全有效的(如果不经常   见)代码。

     

init self可能对其他方法有意义,但 init 呢?当我们调用 init 时,我们正在创建一个对象,那么如何才能有一个自我? Python允许我们扩展   尽管如此,构造对象的自我模式也是如此   它并不完全适合。想象一下jeff = Customer('杰夫   Knupp',1000.0)与调用jeff = Customer(杰夫,杰夫)相同   Knupp',1000.0);传入的杰夫也是结果。

     

这就是为什么当我们调用 init 时,我们通过说来初始化对象   像self.name = name这样的东西。记住,因为自我是实例,   这相当于说jeff.name = name,它与之相同   jeff.name ='杰夫克努普。同样,self.balance = balance也是一样的   如jeff.balance = 1000.0。在这两行之后,我们考虑了   客户对象“已初始化”并可供使用。

     

请注意__init__

     

init 完成后,调用者可以正确地认为   对象已经可以使用了。也就是说,在jeff = Customer('Jeff Knupp'之后,   1000.0),我们可以开始存款并取消对杰夫的电话;杰夫是一个完全初始化的对象。

答案 18 :(得分:-1)

def __init__(self):实际上类似于默认构造函数(例如在Java或其他高级编程语言中。它实际上是用于初始化默认构造函数中的元素,而def is as usual here similar to creating a method here it is a constructor hence in order to initialise few variables at the object initiation call of the class itself and self 类似于{{1 }}运算符,用于访问/引用自己的类对象,例如:

 this