Python'da __init__'den bir değer nasıl döndürülür?


105

__init__İşlevi olan bir sınıfım var .

Bir nesne oluşturulduğunda bu işlevden nasıl bir tamsayı değeri döndürebilirim?

Bir program yazdım, burada __init__komut satırı ayrıştırılıyor ve bazı değer setine ihtiyacım var. Global değişkende ayarlayıp diğer üye işlevlerinde kullanmak tamam mı? Eğer öyleyse bunu nasıl yapmalı? Şimdiye kadar sınıf dışında bir değişken tanımladım. ve bir işlevin ayarlanması başka bir işlevi yansıtmaz mı ??


8
Bir hata kodu döndürmeyi düşünüyorsanız, bunun yerine bir istisna oluşturun.
JoeG

1
Lütfen yorumunuzu kaldırın ve sorunuzu güncelleyin. Sorunun sahibi sizsiniz. Bu senin sorunun. Gerçek sorunun ne olduğunu doğru bir şekilde göstermek için lütfen soruyu düzeltin. Kötüye kullanıyorsun __init__; Gerçekten neyi başarmaya çalıştığınızı anlatırsanız size yardımcı olabiliriz.
S.Lott

Yanıtlar:


120

__init__Yok döndürmek için gereklidir. Başka bir şey iade edemezsiniz (veya en azından vermemelisiniz).

Bir örnek değişkeni (veya işlevi) döndürmek istediğinizi yapmayı deneyin.

>>> 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: Başka bir şey iade edemezsiniz . Hiç mantıklı değil.
S.Lott

73
init yeni oluşturulan nesneyi döndürmez - TypeError'da görüldüğü gibi, None döndürmek gerekir, değil mi? Yeni oluşturulan nesne yeni tarafından döndürülür , init sadece bazı niteliklerini ayarlar. Ama evet, dediğin gibi, başka bir şeyi döndürmek için init'i veya yeniyi değiştirmek gerçekten mantıklı değil.
weronika

Burası newneresi newPython'da örtük mü ? Python'un anlambiliminin Java'dan ve bu sözcüğü kullanan diğer dillerden farklı olduğunu varsaydım.
cs95

1
@Shiva AFAIK, yeni weronika ile genel java semantik değil __yeni __ (kendi) anlamına geliyordu.
Harsh Daftary

2
Bunun yapılamaması, mantıklı olmadığı anlamına gelmez. Örneğin, verileri super().__init__bir örnek değişkeni aracılığıyla aktarmak zorunda kalmadan türetilmiş sınıfa veri aktarmak güzel olurdu .
cz

125

Bunu neden yapmak istersiniz?

Bir sınıf çağrıldığında başka bir nesne döndürmek istiyorsanız, __new__()yöntemi kullanın :

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

obj = MyClass()
print obj

9
Evet, yeni bir sınıfı kullanırken sınıf örneği dışında bir şeyi geri vermenin doğru yolu ... Sadece merak ediyorum - bunu gerçekten YAPMAK isteyebileceğiniz herhangi bir neden var mı?
weronika

34
@weronika Bir fikir: normalde bir fabrikayı kullandığınız her durumda, ancak normal sınıf somutlaştırması gibi görünen bir arayüz sunmak için bazı nedenleriniz var. Örnek: Sınıflarınıza bazı yeni isteğe bağlı parametreler eklerken __init__, gerçekten, istediğiniz esnekliği sağlamak için, özel alt sınıfların örneklerini döndüren bir sınıf fabrikasına ihtiyacınız olduğunu fark edersiniz. Ancak kitaplığınızın kullanıcıları zaten mevcut API'nizi kullanıyor. Bunu korumak için, __new__özelleştirilmiş alt sınıflarınızın örneklerini döndürmek için geçersiz kılarsınız.
Mark Amery

10
Mark Amery'nin söylediği şeyin bir örneğini görmek isterseniz, datetimemodülün kaynak kodunu Standart Kitaplık'tan inceleyin. __new__Tam olarak bu şekilde kullanır .
Zearin

Ayrıca, herhangi biri bunu yapmak isterse, nesneden miras aldığınızdan emin olun, aksi takdirde işe yaramaz.
Mino_e

Bu şakada sadece normal bir işlevi kullanmanın daha mantıklı olduğunu düşünüyorum. Java boyutundan insanlara biraz yabancı olabilir (sınıflarda değil mi? Sapkın!) Ama onun pitonik. (Ayrıca işlevlere özellikler atayabilirsiniz, funtionName.val = .. bu biraz vahşi ama işe yarıyor)
Shayne

37

Gönderen belgelenmesi__init__ :

Yapıcılar üzerinde özel bir kısıtlama olarak, hiçbir değer döndürülemez; bunu yapmak çalışma zamanında bir TypeError hatası oluşmasına neden olur.

Kanıt olarak, bu kod:

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

f = Foo()

Bu hatayı verir:

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

17

Söz konusu konunun Örnek Kullanımı şöyle olabilir:

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)

Yeterince itibarım yok bu yüzden yorum yazamıyorum, bu çılgınlık! Keşke bunu weronika'ya yorum olarak gönderebilseydim


3
Bu NameError yükseltecektir: selftanımlı değil__new__(cls, Item)
Hart Simha

15

__init__Return deyiminin yokluğunda varsayılan olarak diğer yöntemler ve fonksiyonları döner Yok gibi yöntem, bunun bunlardan birini mi yazabilir bu yüzden:

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

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

Ama elbette, eklenmesi return Nonesize hiçbir şey kazandırmaz.

Neyin peşinde olduğundan emin değilim, ama şunlardan biriyle ilgilenebilirsin:

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

f=Foo()
print f.value
print f

baskılar:

42
42

ohh..Sınıfın dışındaki üye değişkenine erişebilir miyim? O zaman bu benim sorunumu
çözmeli

@lakshmipathi, Evet, bunun gibi örnek değişkenleri geneldir.
quamrana

Bir sınıfın başlamasından sonra iade edilen değerli bir şeyi almak için tek rehber olarak:f = Foo().value
JLT

@JLT Evet, kameranız her zaman bunu yaparsınız, ancak yine de herhangi bir şeyin geri döndüğü anlamına gelmez __init__.
quamrana

8

__init__hiçbir şey döndürmez ve her zaman geri dönmelidir None.


4

Bunu bir sınıf değişkenine ayarlayabilir ve ana programdan okuyabilirsiniz:

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

3

init () hiçbir değeri tam olarak çözülmedi

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)

çıktı: hızım 21 kmh


2

Sadece eklemek istedim, sınıfları geri verebilirsiniz __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

Yukarıdaki yöntem, testinizdeki bir İstisna üzerine belirli bir eylem uygulamanıza yardımcı olur


2
super().__init__geri dönüyor None, yani geri dönüyorsunuz None, bu iyi, ancak gereksiz.
cz

-2

Eh, artık nesne örneğini önemsemiyorsanız ... onu değiştirebilirsiniz!

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

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

2
Bu sadece selfo kurucu içindeki isme atanan şeyi değiştirir .
Ondrej K.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.