Python - neden bir sınıfta "self" kullanılsın?


82

Bu 2 sınıf nasıl farklılık gösterir?

class A():
    x=3

class B():
    def __init__(self):
        self.x=3

Önemli bir fark var mı?


6
hayır, kopya değil.

1
@hop: İlginç bir iddia, ancak bunun kopya olmadığına dair herhangi bir örnek veya kanıt sunmadınız. Neden öyle diyorsun?
S.Lott

2
@ S.Lott - Huh? Diğer soru, neden kendimizi açıkça geçirmemiz gerektiğini sormaktır. Bu, sınıf ve örnek değişkenleri nedeniyle farkı soruyor.
Dana

1
@ S.Lott Bu aynı soru değil. Hatta sormadan önce ona baktım.
ryeguy

2
@ S.Lott: 68282, neden kendini yöntemlere ilk argüman olarak açıkça koymanız gerektiğine dair gereksiz bir soru; bu soru, sınıf ve örnek üyeleri arasındaki farkı sorar. S.Lott, SO'ya katkılarınızı gerçekten çok seviyorum, ancak bu sefer yanılıyorsunuz.

Yanıtlar:


137

A.xbir sınıf değişkenidir . B's self.xbir örnek değişkendir .

yani A'nin xörnekleri arasında paylaşılır.

Bir liste gibi değiştirilebilen bir şeyle farkı göstermek daha kolay olurdu:

#!/usr/bin/env python

class A:
    x = []
    def add(self):
        self.x.append(1)

class B:
    def __init__(self):
        self.x = []
    def add(self):
        self.x.append(1)

x = A()
y = A()
x.add()
y.add()
print("A's x:", x.x)

x = B()
y = B()
x.add()
y.add()
print("B's x:", x.x)

Çıktı

A's x: [1, 1]
B's x: [1]

8
Belki senaryonuzun çıktısını da gönderin, o zaman kişi onu kopyalayıp çalıştırmadan farkı görebilir ...
Martin

2
Python'un benliği Java'nınkine eşdeğer mi? Noobishness izin verin lütfen
Jean Azzopardi

2
@Jean - Yes-ish - self, örnek yöntemlerinin ilk parametresine verilen geleneksel ad olmalıdır - ve python, örnek yöntemlerinin ilk argümanı olarak örnek yöntemlerinin geçerli örneğini açıkça iletir. Ama Java'nınki ile aynı işi yapıyor
Douglas Leeder

@Jean Azzopardi: self neredeyse Java (ve c ++) gibi. Benlik basitçe gereklidir; bu bazen Java derleyicisi tarafından gerekçelendirilir (diğer zamanlarda gereklidir.)
S.Lott

@Douglas Leeder - sorun değil.
UnkwnTech

56

Sadece bir yan not olarak: selfaslında sadece rastgele seçilmiş bir kelime, herkesin kullandığı, ancak aynı zamanda kullanabilirsiniz this, fooya myselfveya başka bir şey, istediğiniz bir sınıf için olmayan her statik yöntemin sadece ilk parametre var. Bu, kelimenin selfbir dil yapısı değil, sadece bir isim olduğu anlamına gelir :

>>> class A:
...     def __init__(s):
...        s.bla = 2
... 
>>> 
>>> a = A()
>>> a.bla
2

1
Neden bu bir cevap ve yorum değil
Gabriel Petersson

23

Ax, bir sınıf değişkenidir ve bir örnek içinde özellikle geçersiz kılınmadıkça, A'nın tüm örneklerinde paylaşılacaktır. Bx bir örnek değişkendir ve her B örneğinin kendi sürümü vardır.

Umarım aşağıdaki Python örneği açıklığa kavuşur:


    >>> class Foo():
    ...     i = 3
    ...     def bar(self):
    ...             print 'Foo.i is', Foo.i
    ...             print 'self.i is', self.i
    ... 
    >>> f = Foo() # Create an instance of the Foo class
    >>> f.bar()
    Foo.i is 3
    self.i is 3
    >>> Foo.i = 5 # Change the global value of Foo.i over all instances
    >>> f.bar()
    Foo.i is 5
    self.i is 5
    >>> f.i = 3 # Override this instance's definition of i
    >>> f.bar()
    Foo.i is 5
    self.i is 3

17

Bunu bu örnekle açıklardım

# By TMOTTM

class Machine:

    # Class Variable counts how many machines have been created.
    # The value is the same for all objects of this class.
    counter = 0

    def __init__(self):

        # Notice: no 'self'.
        Machine.counter += 1

        # Instance variable.
        # Different for every object of the class.
        self.id = Machine.counter

if __name__ == '__main__':
    machine1 = Machine()
    machine2 = Machine()
    machine3 = Machine()

    #The value is different for all objects.
    print 'machine1.id', machine1.id
    print 'machine2.id', machine2.id
    print 'machine3.id', machine3.id

    #The value is the same for all objects.
    print 'machine1.counter', machine1.counter
    print 'machine2.counter', machine2.counter
    print 'machine3.counter', machine3.counter

Çıktı daha sonra

machine1.id 1
machine2.id 2
machine3.id 3

makine1. sayaç 3
makine2. sayaç 3
makine3. sayaç 3

3

Python öğrenmeye yeni başladım ve bu bir süredir kafamı karıştırdı. Genel olarak nasıl çalıştığını anlamaya çalışırken şu çok basit kod parçasını buldum:

# Create a class with a variable inside and an instance of that class
class One:
    color = 'green'

obj2 = One()


# Here we create a global variable(outside a class suite).
color = 'blue'         

# Create a second class and a local variable inside this class.       
class Two:             
    color = "red"

    # Define 3 methods. The only difference between them is the "color" part.
    def out(self):     
        print(self.color + '!')

    def out2(self):
        print(color + '!')

    def out3(self):
        print(obj2.color + '!')

# Create an object of the class One
obj = Two()

Aradığımızda şunu alırız out():

>>> obj.out()

red!

Aradığımızda out2():

>>> obj.out2()

blue!

Aradığımızda out3():

>>> obj.out3()

green!

Bu nedenle, ilk yöntemde selfPython'un oluşturduğumuz sınıf nesnesine "ait olan" değişkeni (özniteliği) kullanması gerektiğini belirtir, genel bir nesneye değil (sınıfın dışında). Yani kullanır color = "red". Yöntemde, Python örtük olarak selfoluşturduğumuz bir nesnenin adını değiştirir ( obj). self.colorvasıta "Ben alıyorum color="red"dan obj"

İkinci yöntemde selfrengin alınacağı nesneyi belirtmeye gerek olmadığı için global olanı alır color = 'blue'.

Yerine üçüncü yöntemde selfKullandığımız obj2- Başka nesnenin bir isim almak için colorgelen. Alır color = 'green'.

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.