Pythonで__init__から値を返す方法は?


101

__init__関数のあるクラスがあります。

オブジェクトが作成されたときに、この関数から整数値を返すにはどうすればよいですか?

__init__コマンドライン解析を行うプログラムを作成しました。値を設定する必要があります。グローバル変数に設定して他のメンバー関数で使用しても問題ありませんか?もしそうなら、それをどのように行うのですか?これまでのところ、クラス外の変数を宣言しました。そして、それを1つの機能に設定すると、他の機能に反映されませんか?


8
エラーコードを返すことを検討している場合は、代わりに例外を発生させます。
JoeG 2010年

1
コメントを削除して、質問を更新してください。あなたは質問を所有しています。それはあなたの質問です。質問を修正して、実際の問題を正しく示してください。あなたは誤用してい__init__ます。あなたが本当に達成しようとしていることを説明すると、私たちはあなたを助けることができます。
S.Lott、2010年

回答:


116

__init__Noneを返すために必要です。あなたは何か他のものを返すことはできません(または少なくともすべきではありません)。

インスタンス変数(または関数)を返したいものは何でも作ってみてください。

>>> class Foo:
...     def __init__(self):
...         return 42
... 
>>> foo = Foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() should return None

24
+1:他のもの返せません。意味がありません。
S.Lott、2010年

72
initは新しく作成されたオブジェクトを返しません-TypeErrorに見られるように、Noneを返す必要がありますよね?新しく作成されたオブジェクトはnewによって返され、initはその属性の一部を設定するだけです。しかし、はい、あなたが言ったように、何かを返すためにinitまたはnewを変更することは、本当に意味がありません。
ウェロニカ

ここはどこnewnewPython では暗黙的ですか?PythonのセマンティクスはJavaやこの単語を使用する他の言語とは異なると思いました。
cs95 2016

1
@Shiva AFAIK、新しいウェロニカとは、一般的なJavaセマンティクスではなく__new __(self)を意味しました。
Harsh Daftary、

2
それができないからといって、それが意味をなさないということではありません。たとえば、super().__init__インスタンス変数を介してデータをリレーせずに、派生クラスにデータを渡すと便利です。
2018年

123

なぜそうしたいのですか?

クラスが呼び出されたときに他のオブジェクトを返したい場合は、次の__new__()メソッドを使用します。

class MyClass(object):
    def __init__(self):
        print "never called in this case"
    def __new__(cls):
        return 42

obj = MyClass()
print obj

9
ええ、新しいのは、クラスを使用するときにクラスインスタンス以外のものを返す正しい方法です。
ウェロニカ

33
@weronika 1つのアイデア:通常はファクトリを使用するが、通常のクラスのインスタンス化のように見えるインターフェースを提示したい場合があります。例:クラス__init__のに新しいオプションのパラメーターを追加すると、必要な柔軟性を提供するには、特殊なサブクラスのインスタンスを返すクラスファクトリが必要であることがわかります。ただし、ライブラリのユーザーはすでに既存のAPIを使用しています。これを保持するには、オーバーライド__new__して、特殊なサブクラスのインスタンスを返します。
マークアメリー2014年

10
Mark Ameryの発言の例を見たい場合datetimeは、標準ライブラリからモジュールのソースコードをチェックしてください。それは__new__まさにこの方法で使用します。
ゼアリン

また、誰かがこれを実行したい場合は、オブジェクトから継承してください。そうしないと機能しません。
Mino_e 2017

この一見では、通常の関数を使用する方が理にかなっていると思います。Javaの次元(関数がクラスにない?異端!)からは少し異質かもしれませんが、そのPythonはそうです。(funtionName.val = ..のように関数にプロパティを割り当てることもできます。これはワイルドですが機能します)
Shayne

37

ドキュメントから__init__

コンストラクタに対する特別な制約として、値を返すことはできません。これを行うと、実行時にTypeErrorが発生します。

証明として、このコード:

class Foo(object):
    def __init__(self):
        return 2

f = Foo()

このエラーを与えます:

Traceback (most recent call last):
  File "test_init.py", line 5, in <module>
    f = Foo()
TypeError: __init__() should return None, not 'int'

17

問題の問題の使用例は次のようになります。

class SampleObject(object):

    def __new__(cls, item):
        if cls.IsValid(item):
            return super(SampleObject, cls).__new__(cls)
        else:
            return None

    def __init__(self, item):
        self.InitData(item) #large amount of data and very complex calculations

...

ValidObjects = []
for i in data:
    item = SampleObject(i)
    if item:             # in case the i data is valid for the sample object
        ValidObjects.append(item)

評判が足りないのでコメントが書けません、すごいです!weronikaへのコメントとして投稿したい


3
これによりNameErrorが発生します:selfは定義されていません__new__(cls, Item)
Hart Simha

15

この__init__メソッドは、他のメソッドや関数と同様に、returnステートメントがない場合、デフォルトでNoneを返すため、次のいずれかのように記述できます。

class Foo:
    def __init__(self):
        self.value=42

class Bar:
    def __init__(self):
        self.value=42
        return None

ただし、もちろん、を追加しreturn Noneても何も購入されません。

あなたが何を求めているのかはわかりませんが、次のいずれかに興味があるかもしれません。

class Foo:
    def __init__(self):
        self.value=42
    def __str__(self):
        return str(self.value)

f=Foo()
print f.value
print f

プリント:

42
42

ohh ..クラスのメンバー変数にアクセスできますか?それで私の問題は解決するはずです.... thanks
webminal.org

@lakshmipathi、はい、このようなインスタンス変数はパブリックです。
quamrana

クラスの開始後に何か価値のあるものを返すためのワンライナーとして:f = Foo().value
JLT

@JLTはい、常にそうしますが、それでもから何も返されないという意味ではありません__init__
quamrana 16


4

クラス変数に設定して、メインプログラムから読み取るだけです。

class Foo:
    def __init__(self):
        #Do your stuff here
        self.returncode = 42
bar = Foo()
baz = bar.returncode

2

追加したいだけで、クラスを返すことができます __init__

@property
def failureException(self):
    class MyCustomException(AssertionError):
        def __init__(self_, *args, **kwargs):
            *** Your code here ***
            return super().__init__(*args, **kwargs)

    MyCustomException.__name__ = AssertionError.__name__
    return MyCustomException

上記の方法は、テストの例外時に特定のアクションを実装するのに役立ちます


2
super().__init__が戻ってNoneきているので、あなたは戻ってきてNoneいます。これは問題ありませんが、冗長です。
2018年

2

init()完全に解決された値を返さない

class Solve:
def __init__(self,w,d):
    self.value=w
    self.unit=d
def __str__(self):
    return str("my speed is "+str(self.value)+" "+str(self.unit))
ob=Solve(21,'kmh')
print (ob)

出力:私の速度は21 kmhです


-2

さて、オブジェクトインスタンスが不要になった場合は、単に置き換えることができます。

class MuaHaHa():
def __init__(self, ret):
    self=ret

print MuaHaHa('foo')=='foo'

2
これはself、コンストラクタ内で名前に割り当てられているものを変更するだけです。
Ondrej K.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.