0

I am fairly new to python, and currently working on a project. Following is my Dimension class :

class Dimension:
    dpi = 0
    padding_x = 200 * dpi
    padding_y = 100 * dpi

I am setting the dpi value from another class called Splash:

class Splash:
if __name__ == '__main__':
    Dimension.dpi = 1.6
    print("x padding : {}".format(Dimension.padding_x))  # prints 0

So my problem is, while I get the value of dpi as 1.6 if I try to print it, the corresponding value of padding_x or padding_y is 0 even after I have set dpi value. When the variable dpi's value is changed, shouldn't the padding_x or y's value also be changed?

Aman Grover
  • 45
  • 1
  • 10
  • 1
    "When the variable dpi's value is changed, shouldn't the padding_x or y's value also be changed?" no, there's no reason in this code for it to do that. You could use a method to update `dpi` and `padding_x` and `padding_y` at the same time – juanpa.arrivillaga Jul 01 '20 at 08:56
  • ok, got it, I have one more doubt, in Java static variables can only be referenced from static methods, is it the same in python? Should I update all static variable's values from a static method? – Aman Grover Jul 01 '20 at 09:12
  • No. That doesn't work that way in Python at all. Static methods are practically useless. Mostly, you'd use a `@classmethod` – juanpa.arrivillaga Jul 01 '20 at 09:30
  • Why is `if __name__ == '__main__'` in the class block? Is that a copy-paste error – juanpa.arrivillaga Jul 01 '20 at 09:35
  • I haven't shared the whole code, just the code snippet to better make you understand what I am trying to ask. – Aman Grover Jul 01 '20 at 09:53
  • that makes things confusing. please provide [mcve] when you post a question – juanpa.arrivillaga Jul 01 '20 at 09:54
  • Actually this is a project in tkinter I am using, and this splash class is my entry point into the app, i.e the first class that is run – Aman Grover Jul 01 '20 at 09:54
  • That doesn't make any sense. – juanpa.arrivillaga Jul 01 '20 at 09:55
  • ok, but I got this project like this only, as I am still learning, I don't know if this is the right way to do this. Can you explain what is wrong with using `if __name__ == '__main__'` block? – Aman Grover Jul 01 '20 at 09:58
  • That it doesn't make any sense. That is the idiom used to protect code from running when a module is imported, so in some other module, `import mymodule`, but that code will run when you do `python mymodule.py`. Read more about it [here](https://stackoverflow.com/questions/419163/what-does-if-name-main-do) It doesn't make any sense to have code in a class definition executed conditionally like that. The entry point to a program in Python is *always a module*, it's not a class with a `main` method like in Java. – juanpa.arrivillaga Jul 01 '20 at 10:01
  • ok, So I could have just used `__init__()` to do the same work I have done in `__main__` block? – Aman Grover Jul 01 '20 at 10:04
  • No? Maybe? Again, **that just doesn't make any sense in a class definition**. Just remove that `if` statement and put it directly in the class. – juanpa.arrivillaga Jul 01 '20 at 10:05
  • ok, now I have got it, thankyou. Here the `if` statement is useless. – Aman Grover Jul 01 '20 at 10:07

1 Answers1

1

You declared dpi to be 0 and because you are using these variables as static variables it will retain its original values. Static variables retain value regardless of the instance of the object. What you should do is:

class Dimension:
    dpi = 0
    padding_x = 200
    padding_y = 100
    def __init__(self):
        self.padding_x = self.padding_x*self.dpi

class Splash:
    if __name__ == '__main__':
        Dimension.dpi = 1.6
        a = Dimension()
        print("x padding : {}".format(a.padding_x))

you can still use the dpi as a static variable but it would be better to utilize the constructor toinitialize the other variables

if you still want to use as static the do this:

class Dimension:
    dpi = 0
    padding_x = 200
    padding_y = 100

class Splash:
    if __name__ == '__main__':
        Dimension.dpi = 1.6;
        Dimension.padding_x=200*Dimension.dpi
        print("x padding : {}".format(Dimension.padding_x)) 

using a static method to change the values:

class Dimension:
    dpi = 0
    padding_x = 200
    padding_y = 100
    @staticmethod
    def static(dpi):
        Dimension.dpi = dpi
        Dimension.padding_x *= Dimension.dpi
        Dimension.padding_y *= Dimension.dpi
class Splash:
    if __name__ == '__main__':
        Dimension.static(1.6);
        print("x padding : {}".format(Dimension.padding_x)) 
Night King
  • 455
  • 4
  • 12
  • If I am calling the value of padding_x as a.padding_x, isn't the variable now converted to class variable instead of static variable as it was? – Aman Grover Jul 01 '20 at 09:07
  • if you want to use as a static variable then u have reinitialize it as @juanpa.arrivillaga suggested – Night King Jul 01 '20 at 09:09
  • @user2278116 see edited answer and notify if its wat u want to do – Night King Jul 01 '20 at 09:12
  • actually I wanted to change those values from within the dimension class. Is it possible? Like if I set a value for dpi and then call some method which can change all the other variable's value based on dpi's value? In this process I want those static variables to remain static. Is it possible? – Aman Grover Jul 01 '20 at 09:15
  • @user2278116 the third code block uses a staticmethod to change the values. Is this want you intended – Night King Jul 01 '20 at 09:22
  • ok yes, thankyou. I had doubts about changing static variable values from static or non static methods. This cleared things up. – Aman Grover Jul 01 '20 at 09:27
  • 1
    It probably makes more sense to use a `@classmethod` – juanpa.arrivillaga Jul 01 '20 at 09:31
  • @juanpa.arrivillaga correct but i thiink staticmethods is cleaner solution – Night King Jul 01 '20 at 09:33
  • This `Splash` class makes no sense to begin with – juanpa.arrivillaga Jul 01 '20 at 09:35
  • @juanpa.arrivillaga the question owner is probably learning. and most learning code actually make no sense FooBar :) – Night King Jul 01 '20 at 09:36
  • @juanpa.arrivillaga it would be really helpful if you can make me understand where I am going wrong with in Splash class? Criticize the code as much as you want, but do point out my errors too, that is the only way I can learn faster. – Aman Grover Jul 01 '20 at 09:52
  • @user2278116 I asked about it in the comments above. What is `if __name__ == '__main__` doing in a class block? – juanpa.arrivillaga Jul 01 '20 at 09:52
  • @user2278116 can u mark answer as correct for others that stumble across this problem – Night King Jul 01 '20 at 09:55
  • 1
    @user2278116 https://stackoverflow.com/questions/419163/what-does-if-name-main-do#:~:text=In%20short%2C%20use%20this%20%27%20if,when%20the%20module%20is%20imported.&text=Put%20simply%2C%20__name__,run%20as%20an%20imported%20module. – Night King Jul 01 '20 at 09:59
  • So, is the `__name__ == '__main__'` block useless here? I could have used `__init__()` initializer method? – Aman Grover Jul 01 '20 at 10:02
  • @user2278116 go checkout `__name__ == '__main__'` what it does first and understand it – Night King Jul 01 '20 at 10:03
  • @user2278116 `if __name__ == "__main__"` does nothing here, but it has nothing to do with `__init__` either, it is an intiialzer/constructor, `if __name__ == '__main__'` is an idiom that generally goes in the global/module scope – juanpa.arrivillaga Jul 01 '20 at 10:07