首页 文章

Python __init__和self他们做了什么?

提问于
浏览
609

我正在学习Python编程语言,而且我遇到了一些我不太了解的东西 .

在如下方法中:

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

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

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

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

18 回答

  • 149

    Python __init__和self他们做了什么?自我做什么?这是什么意思?这是强制性的吗? __init__方法有什么作用?为什么有必要? (等等 . )

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

    class SomeObject(object):
    
        def __init__(self, blah):
            self.blah = blah
    
        def method(self):
            return self.blah
    

    当我们创建对象的实例时,会调用 __init__ 来在创建对象后对其进行自定义 . 也就是说,当我们用 'blah' 调用 SomeObject (可能是任何东西)时,它会作为参数 blah 传递给 __init__ 函数:

    an_object = SomeObject('blah')
    

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

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

    an_object.method()
    

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

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

    隐式传递的 self 参数按惯例称为 self . 我们可以使用任何其他合法的Python名称,但如果您将其更改为其他内容,您可能会被其他Python程序员使用 .

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

  • 25

    一个简短的说明性例子

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

    class MyClass(object):
         i = 123
         def __init__(self):
             self.i = 345
    
    a = MyClass()
    print a.i
    345
    print MyClass.i
    123
    
  • 3

    __init__ 确实像构造函数一样 . 如果您希望它们作为非静态方法运行,则需要将"self"传递给任何类函数作为第一个参数 . "self"是您 class 的实例变量 .

  • 20

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

    要正确理解 __init__ 方法,您需要了解自己 .

    The self Parameter

    __init__ 方法接受的参数是:

    def __init__(self, arg1, arg2):
    

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

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

    额外的争论来自哪里?

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

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

    Whenever a method is called, a reference to the main object is passed as the first argument. 按照惯例,你总是将这个第一个参数称为你的方法self .

    这意味着在 __init__ 方法中我们可以做到:

    self.arg1 = arg1
    self.arg2 = arg2
    

    Here we are setting attributes on the object. 您可以通过执行以下操作来验证这一点:

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

    像这样的值称为对象属性 . Here the init method sets the arg1 and arg2 attributes of the instance.

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

  • 11

    是的,你是对的,这些是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 对象的成员(可在对象的生命周期内访问) .

  • 14

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

    每个类方法的第一个参数,包括init,总是 reference to the current instance of the clas . 按照惯例,这个参数总是命名为self . 在init方法中,self引用新创建的对象;在其他类方法中,它指的是调用其方法的实例 .

    Python doesn't force you on usingself ” . 你可以给它任何你想要的名字 . 但请记住,方法定义中的第一个参数是对object的引用.Python为您添加self参数到列表中;调用方法时不需要包含它 . 如果你没有在init方法中提供self,那么你将收到一个错误

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

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

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

  • 14

    在这码:

    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
    
  • 1

    只是一个问题的演示 .

    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
    
  • 198

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

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

    自我?那么所有Customer方法的self参数是什么?它是什么?为什么,这是实例,当然!换句话说,像撤回这样的方法定义了从某个抽象客户的账户中提取资金的指令 . 调用jeff.withdraw(100.0)将这些指令放在jeff实例上使用 . 因此,当我们说退出(自我,金额)时,我们会说,“这就是你如何从客户对象(我们称之为自我)和一个美元数字(我们称之为金额)中提取资金 . ”是调用撤销的客户的实例 . 这也不是我的类比.jeff.withdraw(100.0)只是Customer.withdraw(jeff,100.0)的简写,这是完全有效的(如果不常见)代码.init self可能对其他方法有意义,但init怎么样?当我们调用init时,我们正在创建一个对象,那么怎样才能有一个self?Python允许我们将自我模式扩展到当构造对象时,即使它不完全适合 . 想象一下jeff = Customer('Jeff Knupp',1000.0)与调用jeff = Customer(jeff,'Jeff Knupp',1000.0)相同;传入的jeff也是结果 . 这就是为什么当我们调用init时,我们通过说self.name = name之类的东西初始化对象 . 记住,因为self是例如,这相当于说jeff.name = name,这与jeff.name ='Jeff Knupp相同 . 同样,self.balance = balance与jeff.balance = 1000.0相同 . 在这两行之后,我们认为Customer对象已“初始化”并可以使用 . 小心你__init__在init完成后,调用者可以正确地假设该对象已经可以使用了 . 也就是说,在jeff = Customer('Jeff Knupp',1000.0)之后,我们可以开始存款并取消对杰夫的电话;杰夫是一个完全初始化的对象 .

  • 3

    简而言之:

    • self 正如它所暗示的那样,指自己 - 调用该方法的对象 . 也就是说,如果你有N个对象调用该方法,那么 self.a 将为每个N个对象引用一个单独的变量实例 . 想象一下每个对象的变量 a 的N个副本

    • __init__ 是其他OOP语言(如C / Java)中的构造函数 . 基本思想是它是一种特殊的方法,在创建该类的对象时自动调用

  • 4
    # 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()
    
  • 22

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

  • 16

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

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

    class MyClass:
        """A simple example class"""
        i = 12345
    
        def f(self):
            return 'hello world'
    

    然后 MyClass.iMyClass.f 是有效的属性引用,分别返回一个整数和一个函数对象 . 也可以为类属性分配,因此您可以通过赋值更改 MyClass.i 的值 . __doc__ 也是一个有效属性,返回属于该类的文档字符串:"A simple example class" .

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

    x = MyClass()
    

    instantiation 操作(“调用”类对象)创建一个空对象 . 许多类喜欢创建具有针对特定初始状态定制的实例的对象 . 因此,类可以定义一个名为 __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 :)
    
  • 6

    试试这段代码 . 希望它能帮助像我这样的许多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

  • 12
    • init 基本上是一个函数,它将 "initialize" / "activate" 特定对象的类的属性,一旦创建并匹配到相应的类 .

    • self 表示将继承这些属性的对象 .

  • 37

    在这段代码中:

    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') )也将作为参数传递 - 在这种情况下会引发异常,因为构造函数不期望它们 .

  • 488

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

    class A(object):
        def __init__(foo):
            foo.x = 'Hello'
    
        def method_a(bar, foo):
            print bar.x + ' ' + foo
    

    它的工作方式完全相同 . 但是建议使用self,因为其他pythoners会更容易识别它 .

  • 7

    'self'是对类实例的引用

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

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

    f = foo()
    f.bar()
    

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

    f = foo()
    foo.bar(f)
    

    有趣的是,变量名称'self'只是一个约定 . 下面的定义将完全相同..已经说 very strong convention 应该遵循 always ,但它确实说了一些关于语言的灵活性

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

相关问题