1

i created this class for my homework:

class sayfa():
    isim=" "
    def __init__(self,bSayisi,ySayisi,pSayisi,iSayisi,tSayisi):
        self.bSayisi=bSayisi
        self.ySayisi=ySayisi
        self.pSayisi=pSayisi
        self.iSayisi=iSayisi
        self.tSayisi=tSayisi
        if ((((bSayisi+ySayisi+pSayisi)/iSayisi)/tSayisi)*100)>0.2:
             print(isim,"başarılı")
        else:
             print(isim,"başarısız")

then i called it in another .py file:

from eRate import sayfa


ybs1=sayfa(365000,65000,870,500,1125000)
ybs1.isim="YBS-1"

then i tried to work it and it gave me this error:

NameError: name 'isim' is not defined

I think i did something wrong when i'm writing class but i don't know what i actually done wrong.Can you help me?

edit: My code worked when i put isim variable in def init but it looks weird.It looks like this:

class sayfa():

    def __init__(self,bSayisi,ySayisi,pSayisi,iSayisi,tSayisi,isim):
        self.isim=str(isim)
        self.bSayisi=bSayisi
        self.ySayisi=ySayisi
        self.pSayisi=pSayisi
        self.iSayisi=iSayisi
        self.tSayisi=tSayisi
        if ((((bSayisi+ySayisi+pSayisi)/iSayisi)/tSayisi)*100)>0.2:
             print(isim,"başarılı")
        else:
             print(isim,"başarısız")

and when i'm adding data in class it gets weirder:

from eRate import sayfa


ybs1=sayfa(365000,65000,870,500,1125000,"YBS-1")

3 Answers3

1

The error isn't with the way you're assigning things, but with the way you're accessing them.

Just as you have to do self.bSayisi to set an attribute, you have to do self.isim to access one. So:

print(self.isim, "başarılı")

(and the same for the other line…)


If you're wondering why you were able to access other values like bSayisi without self.bSayisi—that's just because you happen to have a parameter named bSayisi that happens to have the same value as self.bSayisi (because you just made that true a few lines earlier). If you changed it to, say, self.bSayisi = bSayisi*2, or you renamed the parameter to myBSayisi and did self.bSayisi = myBSayisi, you'd see that just using bSayisi instead of self.bSayisi was no longer correct.


However, while this eliminates the error, I'm not sure it actually does what you want. At the time you're doing this print, you haven't assigned an isim value to the object yet, so it's going to get the class value as a default, so it's always just going to be " ". Is that really what you wanted?

If not, you need to move the print calls to some other method that you can call later, after having assigned isim. For example:

class sayfa():
    isim=" "
    def __init__(self,bSayisi,ySayisi,pSayisi,iSayisi,tSayisi):
        self.bSayisi=bSayisi
        self.ySayisi=ySayisi
        self.pSayisi=pSayisi
        self.iSayisi=iSayisi
        self.tSayisi=tSayisi
    def displaystuff(self):
        if ((((self.bSayisi+self.ySayisi+self.pSayisi)/self.iSayisi)/self.tSayisi)*100)>0.2:
             print(self.isim,"başarılı")
        else:
             print(self.isim,"başarısız")

ybs1=sayfa(365000,65000,870,500,1125000)
ybs1.isim="YBS-1"
ybs1.displaystuff()

Of course moving the isim into the constructor works, by avoiding the problem you were running into. It's not an answer to how to add data after the __init__ method, of course, because you're instead adding the data in the __init__ method. When that's appropriate, it's the simplest answer.

But if it looks weird in this case (I'll take your word for it; I don't know exactly what this code is trying to do), it's probably the wrong answer for this particular class.

In which case, you do need to know how to add data after the __init__ method, as you asked. Or, rather, you need to know how to access that data—because you were already adding it correctly.

abarnert
  • 354,177
  • 51
  • 601
  • 671
1

This is the difference between class attributes (when it is outside of the __init__ with no self.) and instance attributes (when you added it inside the __init__ with the self.).

Class attributes are a little more complicated since they pertain to all the instances of that class (you could overwrite them within some instances, but then they'd become instance attributes in those cases)... and so if you changed a class attribute, it would affect all other instances you may have created or will create in the future.

For a more in-depth discussion of class attributes vs instance attributes see this answer that summarizes this post.

WillMonge
  • 1,005
  • 8
  • 19
0

Normall __init__(..) is used to initialize / instantiate your instance. I would not print in it, nor calculate (unless you calculate some other class-variables and set them).

You need to prefix your variables of the instance by self. and the static class variable with the class name to acess it:

class sayfa():
    isim=" " # this is a shared class variabl (aka static)

    def __init__(self,bSayisi,ySayisi,pSayisi,iSayisi,tSayisi):
        self.bSayisi=bSayisi   # these are all instance variables, not shared
        self.ySayisi=ySayisi
        self.pSayisi=pSayisi
        self.iSayisi=iSayisi
        self.tSayisi=tSayisi
        self.unusedSum = ySayisi + pSayisi + iSayisi 

    def printMe(self):    # lookup __str__() and __repr__() for how to output your instance
        if ((((self.bSayisi+self.ySayisi+self.pSayisi)/self.iSayisi)/self.tSayisi)*100)>0.2:
             print(sayfa.isim,"some text") # use the static class variable
        else:
             print(sayfa.isim,"some other text")

sayfa.isim = "Coffee "  # you set static class variables by prefixing class name

my_sayfa_instance    = sayfa(365000,65000,870,500,1125000)
other_sayfa_instance = sayfa(3600,65000,870,500,10)

my_sayfa_instance.printMe()
other_sayfa_instance.printMe()

Output:

Coffee  some other text
Coffee  some text
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69