Python __init__和self他们做了什么?

737 python oop self

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

在如下方法中:

def method(self, blah):
    def __init__(?):
        ....
    ....
Run Code Online (Sandbox Code Playgroud)

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

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

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

Chr*_* B. 552

在这段代码中:

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

    def method_a(self, foo):
        print self.x + ' ' + foo
Run Code Online (Sandbox Code Playgroud)

... 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
Run Code Online (Sandbox Code Playgroud)

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

  • 值得指出的是,第一个参数不一定被称为“self”,它只是按照惯例。 (176认同)
  • 它就像一个静态变量。它只初始化一次,可以通过 `Ax` 或 `ax` 访问。请注意,在特定类上覆盖它不会影响基类,因此 `Ax = 'foo'; ax = 'bar'; 打印斧头;打印 Ax` 将打印 `bar` 然后是 `foo` (18认同)
  • 如果你把 `x = 'Hello'` 放在 __init__ 外面但放在类里面怎么办?它是像 java 一样的地方,还是变得像一个只初始化一次的静态变量? (13认同)
  • 类声明中`object`有什么意义?我注意到有些课程有这个,有些则没有 (13认同)
  • @Chris它适用于Python 2兼容性.在Python 3中,不需要显式继承`object`,因为它默认发生. (8认同)

Red*_*ing 230

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

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

class Point:
    def __init__(self, x, y):
        self._x = x
        self._y = y
Run Code Online (Sandbox Code Playgroud)

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

x = Point(1,2)
Run Code Online (Sandbox Code Playgroud)

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

class Point:
    def __init__(self, x, y):
        _x = x
        _y = y
Run Code Online (Sandbox Code Playgroud)

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

  • @black答案的文本实际上是“分配对象的内存时调用 __init__ 方法”。它没有说 __init__ 分配内存,而是说它在分配内存时被调用。也许值得通过将“何时”更改为“之后”来澄清:) (8认同)
  • 那么,你有什么理由不希望 `self` 出现在构造函数中吗?为什么还要指定它,如果是隐式的不是更好吗? (2认同)
  • 据我所知, __ init __ 不是构造函数,它是创建任何对象时将执行的第一个方法, __ init __ 用于设置对象。__ new __是python中的构造函数。 (2认同)

Dav*_*itt 187

一个简短的例子

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

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

a = MyClass()
print(a.i)
print(MyClass.i)
Run Code Online (Sandbox Code Playgroud)

  • 这就是我试图用这个例子"向自己解释" - 由`__init__`设置的变量是传递给类的*instances*的,而不是类本身具有相同名称的'static'变量... (27认同)
  • 有趣的观察,但我认为你走错了路.使用print MyClass.i,它看起来更像是在调用'静态'变量i.与ai一样,你在调用成员变量,i.在我看来,_init_只是在创建类的对象时首先执行的构造函数. (7认同)

小智 41

简而言之:

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


ewa*_*alk 28

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

  • 'self' 定义一个方法是否是静态的!哇,这让这个 Java 家伙大开眼界。 (3认同)

小智 25

试试这段代码.希望它能帮助像我这样的许多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__
Run Code Online (Sandbox Code Playgroud)

输出:

Jay

Sum = 5

Doc - Inside Class

Doc - __init__ Constructor

Doc - Inside Show

Destructor Deleting object - Jay


eee*_*eee 22

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

要正确理解__init__你需要了解自我的方法.

自我参数

__init__方法接受的参数是:

def __init__(self, arg1, arg2):
Run Code Online (Sandbox Code Playgroud)

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

instance = OurClass('arg1', 'arg2')
Run Code Online (Sandbox Code Playgroud)

额外的争论来自哪里?

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

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

无论何时调用方法,都会将对主对象的引用作为第一个参数传递.按照惯例,你总是将这个第一个参数称为你的方法self.

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

self.arg1 = arg1
self.arg2 = arg2
Run Code Online (Sandbox Code Playgroud)

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

instance = OurClass('arg1', 'arg2')
print instance.arg1
arg1
Run Code Online (Sandbox Code Playgroud)

像这样的值被称为对象属性.这里该__init__方法设置实例的arg1和arg2属性.

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


Har*_*vey 20

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

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

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

    def f(self):
        return 'hello world'
Run Code Online (Sandbox Code Playgroud)

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

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

x = MyClass()
Run Code Online (Sandbox Code Playgroud)

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

def __init__(self):
    self.data = []
Run Code Online (Sandbox Code Playgroud)

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

x = MyClass()
Run Code Online (Sandbox Code Playgroud)

当然,该__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
Run Code Online (Sandbox Code Playgroud)

取自官方文档,最终帮助了我.


这是我的例子

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 :)")
Run Code Online (Sandbox Code Playgroud)

当您创建类Bill的实例时:

purchase = Bill(5,6,7)
Run Code Online (Sandbox Code Playgroud)

你得到:

> Buy 5 apples 6 figs and 7 dates. Total fruitty bill is 18  pieces of
> fruit :)
Run Code Online (Sandbox Code Playgroud)


Sin*_*ion 17

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

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

    def method_a(bar, foo):
        print bar.x + ' ' + foo
Run Code Online (Sandbox Code Playgroud)

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


use*_*111 15

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

  • Python中没有'self'关键字.调用第一个参数'self'只是一个约定. (6认同)

lox*_*sat 15

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

  • 不必使用“self”关键字,它只是一个占位符。可以使用任何单词,但建议您使用 self 以帮助程序的可读性 (2认同)

tar*_*arn 12

'self'是对类实例的引用

class foo:
    def bar(self):
            print "hi"
Run Code Online (Sandbox Code Playgroud)

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

f = foo()
f.bar()
Run Code Online (Sandbox Code Playgroud)

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

f = foo()
foo.bar(f)
Run Code Online (Sandbox Code Playgroud)

有趣的是,变量名称'self'只是一个约定.下面的定义将完全相同..虽然说这是非常强大的惯例,应该始终遵循,但它确实说一些关于语言的灵活性

class foo:
    def bar(s):
            print "hi"
Run Code Online (Sandbox Code Playgroud)


deb*_*bug 11

只是一个问题的演示.

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()
Run Code Online (Sandbox Code Playgroud)
$ 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
Run Code Online (Sandbox Code Playgroud)


小智 8

在这段代码中:

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

这里__init__充当类的构造函数,当实例化对象时,调用此函数.self表示实例化对象.

c = Cat('Kitty')
c.info()
Run Code Online (Sandbox Code Playgroud)

上述陈述的结果如下:

I am a cat and I am called Kitty
Run Code Online (Sandbox Code Playgroud)


Man*_*ddy 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()
Run Code Online (Sandbox Code Playgroud)


Muh*_*han 8

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

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

Python 不会强迫您使用self ”。您可以给它取任何您想要的名称。但是请记住,方法定义中的第一个参数是对对象的引用。Python self为您将参数添加到列表中。调用方法时不需要包含它。如果您没有提供self in init方法,则会收到错误消息

TypeError: __init___() takes no arguments (1 given)
Run Code Online (Sandbox Code Playgroud)

什么是初始化方法吗?为什么有必要?(等等。)

init是初始化的缩写。它是一个构造函数,当您创建类的实例时会调用该构造函数,而不必这样做。但是通常我们的做法是编写用于设置对象默认状态的init方法。如果您最初不愿设置对象的任何状态,则无需编写此方法。


Lax*_*ant 5

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

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

self? 那么所有 Customer 方法的 self 参数是什么?它是什么?为什么,当然是实例!换句话说,像withdraw 这样的方法定义了从某个抽象客户的账户中提取资金的指令。调用 jeff.withdraw(100.0) 将这些指令用于 jeff 实例。

所以当我们说 def 取款(自我,金额):,我们是说,“这是你如何从客户对象(我们称之为 self)和一个美元数字(我们称之为金额)中提取资金。self。是调用撤销的客户的实例。这也不是我在做类比。jeff.withdraw(100.0) 只是 Customer.withdraw(jeff, 100.0) 的简写,这是完全有效的(如果不经常看到)代码。

init self 可能对其他方法有意义,但是init呢?当我们调用init 时,我们正在创建一个对象,那么怎么可能已经有一个 self 呢?Python 允许我们将 self 模式扩展到构造对象时,即使它并不完全适合。想象一下 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__

经过初始化完成后,主叫方可以正确地假定对象就可以使用了。也就是说,在 jeff = Customer('Jeff Knupp', 1000.0) 之后,我们就可以开始对 jeff 进行存款和取款了;jeff 是一个完全初始化的对象。


Aar*_*all 5

Python __init__self它们做什么?

怎么self办?这是什么意思?它是强制性的吗?

__init__方法做什么?为什么有必要?(等等。)

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

class SomeObject(object):

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

    def method(self):
        return self.blah 
Run Code Online (Sandbox Code Playgroud)

当我们创建对象的实例时,将__init__在对象创建后调用,以自定义对象。也就是说,当我们SomeObject'blah'下面的方法(可能是任何东西)进行调用时,它将__init__作为参数传递给函数blah

an_object = SomeObject('blah')
Run Code Online (Sandbox Code Playgroud)

self参数是实例SomeObject,将被分配到an_object

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

an_object.method()
Run Code Online (Sandbox Code Playgroud)

进行点分查找,即将an_object.method实例绑定到该函数的实例,该方法(如上所述)现在是“绑定”方法-这意味着我们无需将实例显式传递给方法调用。

该方法调用获取实例是因为它绑定在点分查找上,并在调用时执行其编程要执行的任何代码。

隐式传递的self参数self由约定调用。我们可以使用其他任何合法的Python名称,但是如果将其更改为其他名称,您可能会被其他Python程序员感到羞耻和and愧。

__init__是一种特殊的方法,在Python数据模型文档中进行了介绍。在创建实例后立即调用它(通常通过__new__-,尽管__new__不是必需的,除非您将不可变的数据类型作为子类)。