Pythonで__init__とselfは何をしますか?


793

私はPythonプログラミング言語を学んでいて、完全に理解していないものに出会いました。

次のような方法で:

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

何をしselfますか?それはどういう意味ですか?必須ですか?

__init__メソッドは何をしますか?なぜ必要なのですか?(等。)

それらはOOPの構成要素かもしれないと思いますが、私はあまり知りません。

回答:


585

このコードでは:

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'))も引数として渡されます。この場合、コンストラクターがそれらを予期していないため、例外が発生します。


8
initのx = 'Hello'外側でクラスの内側に置くとどうなりますか?それは同じであるjavaのようですか、それとも一度だけ初期化される静的変数のようになりますか?
Jayen

15
静的変数のようなものです。初期化は1回のみで、A.xまたはから利用できますa.x。特定のクラスでオーバーライドしてもベースには影響しないため、次に出力A.x = 'foo'; a.x = 'bar'; print a.x; print A.xされることに注意してくださいbarfoo
Chris B.

156
最初の引数は必ずしも呼び出される必要はないことを指摘する価値がありselfます。これは慣例によるものです。
Henry Gomersall

13
ポイント何objectクラス宣言では?一部のクラスにはこれがあるものとないものがあることに気づきました
Chris

9
@Chris Python 2との互換性のためです。Python 3ではobject、デフォルトで発生するため、明示的に継承する必要はありません。
ガブリエル

241

ええ、あなたは正しいです、これらはおっと構造です。

__init__クラスのコンストラクタです。selfパラメータは、(のようなオブジェクトのインスタンスを意味thisC ++で)。

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._xしてself._yのメンバーとしてこれらの変数を設定しPointたオブジェクト(オブジェクトの存続のためにアクセス可能)。


1
それではself、コンストラクタに参加したくない理由はありますか?なぜそれを指定する必要があるのでしょうか?それが暗黙的であった方がいいのではないでしょうか?
アーロンフランケ

私の知る限り、__ init __はコンストラクタではなく、オブジェクトが作成されたときに実行される最初のメソッドです。__init __は、オブジェクトのセットアップに使用されます。__ new __はPythonのコンストラクタです。
Deepanshu

206

簡単な説明例

クラス内で宣言された変数と__init__関数内で宣言された変数の違いを理解するために使用した簡単な例を次に示します。

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

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

出力:

345
123

7
興味深い観察ですが、あなたは間違った軌道に乗っていると思います。印刷MyClass.iを使用すると、「静的」変数iを呼び出しているように見えます。aiと同様に、メンバー変数iを呼び出しています。initは、クラスのオブジェクトを作成するときに最初に実行されるコンストラクタにすぎないようです。
captainspi

34
これが、この例で「自分に説明」しようとしたものです。つまり、によって設定される変数は、クラスのインスタンス__init__渡されるものであり、同じ名前を持つクラス自体の「静的」変数ではありません...
Daveエヴァリット

44

要するに:

  1. selfそれが示唆するように、それ自体を参照します -メソッドを呼び出したオブジェクト。つまり、メソッドを呼び出すN個のオブジェクトがある場合、self.aは、N個のオブジェクトごとに変数の個別のインスタンスを参照します。a各オブジェクトの変数のN個のコピーを想像してください
  2. __init__C ++ / Javaなどの他のOOP言語でコンストラクターと呼ばれるものです。基本的な考え方は、そのクラスのオブジェクトが作成されるときに自動的に呼び出される特別なメソッドであるということです

29

__init__コンストラクタのように動作します。非静的メソッドとして動作させるには、クラス関数に最初の引数として「self」を渡す必要があります。「self」はクラスのインスタンス変数です。


1
'self'は、メソッドが静的かどうかを定義します!うわー、それはこのJavaの人の目を開く人です。
liwevire

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__

出力:

Jay

Sum = 5

Doc - Inside Class

Doc - __init__ Constructor

Doc - Inside Show

Destructor Deleting object - Jay


それが私だけかどうかはわかりませんが、このコードを読むのは少し混乱しました。多分それは私がまだ初心者のPythonプログラマーであるidkが原因です。
リニー

私はドキュメントについてはっきりしていません。それはドキュメントを引っ張っていますか?また、「 '' test-my doc '' '」を使用すると、print.p .__ test__を使用できますか?またはdocは特定のキーワードですか?
トーマス

@Thomas docは、文書化された詳細のキーワードです。三重引用符はドキュメントを書き留めるために使用され、ドキュメントはオプションのエンティティです。
Jayzcode

24

クラスオブジェクトは 2種類の操作をサポートします属性参照とインスタンス化

属性参照は、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」に属する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

結局、私を最も助けてくれた公式のドキュメントから取られました。


これが私の例です

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 :)

22

私自身、これを理解するのに苦労しました。ここで答えを読んだ後でも。

__init__方法を正しく理解するには、自己を理解する必要があります。

自己パラメータ

__init__メソッドが受け入れる引数は次のとおりです。

def __init__(self, arg1, arg2):

ただし、実際には2つの引数のみを渡します。

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

余分な議論はどこから来たのですか?

オブジェクトの属性にアクセスするときは、名前(または参照)で行います。ここでのインスタンスは、新しいオブジェクトへの参照です。instance.printargsを使用して、インスタンスオブジェクトのprintargsメソッドにアクセスします。

__init__メソッド内からオブジェクト属性にアクセスするには、オブジェクトへの参照が必要です。

メソッドが呼び出されるたびに、メインオブジェクトへの参照が最初の引数として渡されます。慣例では、常にこの最初の引数をメソッドselfに呼び出します。

これは、__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


17

self実際には任意の有効なpython識別子である可能性があることに注意してください。たとえば、Chris Bの例から、次のように簡単に書くことができます。

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

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

まったく同じように機能します。ただし、他のpythonはそれをより簡単に認識できるので、selfを使用することをお勧めします。


私はfooの代わりにselfが推奨されることに同意し、他のプログラマーがコードを見るのを助ける
Linny

15

基本的に、同じクラス内の複数の関数で変数を使用する場合は、 'self'キーワードを使用する必要があります。INIT、それが呼び出され、そのクラスの中から、他の機能は、セットアップのデフォルト値に包み使用していないです。


6
Pythonには 'self'キーワードはありません。最初のパラメーターを 'self'と呼ぶのは単なる慣習です。
David Anderson

selfは基本的にプレースホルダーとして使用されます。selfを使用する必要はありません。「eeee」や「foo」などを使用できます。コードを読むときは、他のプログラマーにお勧めです
Linny

15
  1. __init__基本的には、特定のオブジェクトのクラスのプロパティを「初期化」 / 「アクティブ化」する関数であり、作成されて対応するクラスに一致すると、
  2. self それらのプロパティを継承するオブジェクトを表します。

1
「self」キーワードは使用する必要はなく、単なるプレースホルダーです。任意の単語を使用できますが、プログラムを読みやすくするためにselfを使用することをお勧めします
Linny

13

'self'はクラスインスタンスへの参照です

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

これで、fooのインスタンスを作成し、そのメソッドを呼び出すことができます。この場合、Pythonによってselfパラメータが追加されます。

f = foo()
f.bar()

ただし、メソッド呼び出しがクラスのインスタンスのコンテキストにない場合も渡すことができます。以下のコードは同じことを行います

f = foo()
foo.bar(f)

興味深いことに、変数名 'self'は単なる慣例です。以下の定義はまったく同じように機能します。それは常に従うべき非常に強力な規則であると述べましたが、言語の柔軟な性質について何かを述べています

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

それはなぜ言語の柔軟な性質について何かを言うのですか?それはあなたが変数にあなたが選んだどんな正当な名前を与えることができると言うだけです。他のプログラミング言語とどう違うのですか?
ダニエル

私の回答で書いたように、「バー」はクラスインスタンスが最初のパラメーターとして提供される関数です。したがって、「bar」は「foo」にバインドされたメソッドとして定義されていますが、他のクラスのインスタンスで呼び出すこともできます。これは、たとえばJavaでのメソッドと「this」の動作方法ではありませんが、これらは同じ概念、関数、および一部のインスタンスコンテキスト(インスタンスコンテキストはPythonの最初のパラメーターであり、「this」はJavaの「」)であると思います。 。おそらく、私が参照していた言語の柔軟性がわかるようになるでしょうか?
2014年

ええ、それは言語の柔軟性を示しています。あなたの答えの言い方では、「自己」変数を他のもの(などs)と呼ぶことができるという事実は、Pythonの柔軟性を示していると言っていたようです。
ダニエル

12

質問の単なるデモです。

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

11

このコードでは:

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

11

自己は何をしますか?それどういう意味ですか?それは必須

initを含むすべてのクラスメソッドの最初の引数は、常にクラスの現在のインスタンスへの参照です。慣例により、この引数の名前は常にselfです。initメソッドでselfは、新しく作成されたオブジェクトを参照します。他のクラスメソッドでは、メソッドが呼び出されたインスタンスを参照します。

Python は、self」の使用を強制しません。好きな名前を付けることができます。ただし、メソッド定義の最初の引数はオブジェクトへの参照であることを忘れないでください。Pythonはself引数をリストに追加します。メソッドを呼び出すときにこれを含める必要はありません。initメソッドでselfを指定しなかった場合、エラーが発生します

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

initメソッドは何をしますか?なぜ必要なのですか?(等。)

init初期化の略です。これは、クラスのインスタンスを作成するときに呼び出されるコンストラクタであり、必要ありません。しかし、通常は、オブジェクトのデフォルト状態を設定するためのinitメソッドを作成するのが慣例です。最初にオブジェクトの状態を設定するつもりがない場合は、このメソッドを記述する必要はありません。


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()

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__Python datamodelドキュメントに記載されている特別なメソッドです。これは、インスタンスが作成された直後に呼び出されます(通常は__new__-を使用し__new__ますが、不変のデータ型をサブクラス化しない限り必要ありません)。


3

ここでは、その男はかなり上手でシンプルに書いています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 withdraw(self、amount):と言うときは、「Customerオブジェクト(これをselfと呼びます)とドルの数値(これをamountと呼びます)からお金を引き出す方法です。は、withdrawが呼び出されているCustomerのインスタンスです。これは、私が類似しているわけでもありません。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と同じです。これらの2行の後、Customerオブジェクトは「初期化」され、使用する準備ができていると見なします。

何に気をつけて __init__

後にinitが完了した、呼び出し側は当然、オブジェクトが使用する準備ができていることを前提とすることができます。つまり、jeff = Customer( 'Jeff Knupp'、1000.0)の後で、jeffに対して預金と引き出しの呼び出しを開始できます。jeffは完全に初期化されたオブジェクトです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.