This question already has answers here:
Instance variables in methods outside the constructor (Python) -- why and how?
(7 answers)
Closed 4 years ago.
I'm using PySide2 to define my tool's interface, and I generally initialize all interface items outside __init__ as to not bloat it (any other important variables stay in __init__).
Unfortunately for me, I'm using PyCharm as my editor and it's giving me tons of warnings:
Instance attribute 'foobar' defined outside __init __
Here's a simple example of what I would be doing:
from PySide2 import QtWidgets
class MyTool(QtWidgets.QWidget):
def __init__(self, parent=None):
super(MyTool, self).__init__(parent)
self.create_gui()
def create_gui(self):
# Complains about all variables below!
self.awesome_checkbox = QtWidgets.QCheckBox(parent=self)
self.awesome_button = QtWidgets.QPushButton(parent=self)
self.awesome_label = QtWidgets.QLabel(parent=self)
self.main_layout = QtWidgets.QVBoxLayout()
self.main_layout.addWidget(self.awesome_checkbox)
self.main_layout.addWidget(self.awesome_button)
self.main_layout.addWidget(self.awesome_label)
self.setLayout(self.main_layout)
Now I know one solution would be to initialize these variables in __init__ as None, but I can have fairly complex interfaces so it would be very long winded.
My question is if what I'm currently doing truly blasphemy? I know the variables are technically outside __init__, but the method is being called in the constructor anyways!
Well, the short answer is: no, it's not "truly blasphemy".
It's considered good practice to create all the instance attribute and ensure they are in a consistant state in the initializer because it makes code easier to read (you only have one method to read to know what attributes your object has) and avoids potential AttributeError when an attribute is created by a method that might not always been called before the attribute is accessed. That's why most linters will (by default) warn you about this, and by itself it's a good thing as it can help you spot a potential bug before it makes it's way in production.
Now there are indeed cases where it makes sense to delegate part of the instance initialisation to a distinct method, ie when those attributes depends on each other and some other external factor and might have to be reset / updated together during the instance's lifecycle, or when you want to let child classes override this part of the initialization without having to override the __init__() method itself (cf the GOF's "template method" pattern).
In the case of a class with complex initialization (and this is typical of GUI components) it can also make sense to split the setup in distinct methods for readability reasons - a 50+ lines initializer is not really optimal when it comes to readability - so as far as I'm concerned I would probably do something similar with possibly a couple improvements: first make this a "protected" method (naming it _create_gui() - the leading underscore being the naming convention for protected attributes / methods) and then adding a guard to prevent the method from being executed twice (assuming this method is only supposed to be called once from the initializer and is not supposed to be part of the public API, of course). And then I would add a couple linter directives (those are specially formatted comments that the linter looks for) to make clear for both the linter and anyone reading this code that doing so was a deliberate design choice and not a rookie mistake.
Related
I am writing a class for an image processing algorithm which has some methods, and notably a few static methods. My IDE keeps telling me to convert static methods to function which leads me to the following question:
When should a static method be turned into a function? When shouldn't it?
There are no set rules in python regarding this decision, but there are style-guides defined e.g. by companies that look to solve the ambiguity of when to use what. One popular example of this would be the Google Python Style Guide:
Never use staticmethod unless forced to in order to integrate with an API defined in an existing library. Write a module level function instead.
My guess is, that your IDE follows this stance of a hard no against the staticmethod. If you decide, that you still want to use staticmethods, you can try to disable the warning by adding # noqa as a comment on the line where the warning is shown. Or you can look in your IDE for a setting to disable this kind of warning globally.
But this is only one opinion. There are some, that do see value in using staticmethods (staticmethod considered beneficial, Why Python Developers Should Use #staticmethod and #classmethod), and there are others that argue against the usage of staticmethods (Thoughts On #staticmethod Usage In Python, #staticmethod considered a code smell)
Another quote that is often cited in this discussion is from Guido van Rossum (creator of Python):
Honestly, staticmethod was something of a mistake -- I was trying to
do something like Java class methods but once it was released I found
what was really needed was classmethod. But it was too late to get rid
of staticmethod.
I have compiled a list of arguments that I found, without any evaluation or order.
Pro module-level function:
Staticmethod lowers the cohesion of the class it is in as it is not using any of the attributes the class provides.
To call the staticmethod any other module needs to import the whole class even if you just want to use that one method.
Staticmethod binds the method to the namespace of the class which makes it longer to write SomeWhatDescriptiveClassName.method instead of method and more work to refactor code if you change the class.
Easier reuse of method in other classes or contexts.
The call signature of a staticmethod is the same as that of a classmethod or instancemethod. This masks the fact that the staticmethod does not actually read or modify any object information especially when being called from an instance. A module-level function makes this explicit.
Pro staticmethod:
Being bound by an API your class has to work in, it can be the only valid option.
Possible usage of polymorphism for the method. Can overwrite the staticmethod in a subclass to change behaviour.
Grouping a method directly to a class it is meant to be used with.
Easier to refactor between classmethod, instancemethod and staticmethod compared to module-level functions.
Having the method under the namespace of the class can help with reducing possible namespace-collisions inside your module and reducing the namespace of your module overall.
As I see it, there are no strong arguments for or against the staticmethod (except being bound by an API). So if you work in an organisation that provides a code standard to follow, just do that. Else it comes down to what helps you best to structure your code for maintainability and readability, and to convey the message of what your code is meant to do and how it is meant to be used.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I've recently been dealing a lot with class inheritance on a project I'm working on, and I've started to become disenchanted with it as a programming concept. I do understand its appeal: it provides a clean way to extend an existing base class with new methods, thereby avoiding having to rewrite the same code multiple times and adding a nice logical structure to how classes are related to one another.
However, now that I've been using it more extensively, its drawbacks have become much more apparent. Not only does it add a layer of opacity to where a method or attribute comes from, forcing me to go down a rabbit hole of inherited classes every time I want to figure out where a given method is being defined, but it also breaks encapsulation by allowing you to unwittingly redefine public and private functions and variables in an inherited class.
Here's a very simple example of how easy it is to break things with inheritance.
class Parent:
def __init__(self):
self._private_var = 10
def add_ten(self, n):
return n + self._private_var
class Child(Parent):
def __init__(self):
self._private_var = 100
def add_hundred(self, n):
return n + self._private_var
Now, let's say I want to use Child's inherited .add_ten method:
c = Child()
c.add_ten(4)
>> 104
Since I unknowingly redefined Parent's ._private_var, the .add_ten method now adds 100 instead of 10.
Granted, inheritance might be dealt with slightly differently in other languages (I know Python doesn't have any truly "private" methods or variables, so perhaps this is not as much of an issue in Java or C++). Still, the downsides of inheritance seem to me to outweigh its advantages and make we want to avoid using it altogether if I can.
The issue is that the alternative seems to add a lot of redundancy.
For example, I could have defined ChildTwo as:
class ChildTwo:
def __init__(self):
self._parent = Parent()
self._private_var = 100
def add_ten(self, n):
return self._parent.add_ten(n)
def add_hundred(self, n):
return n + self._private_var
This would allow both .add_ten and .add_hundred to behave as expected, but it would also require me to manually add every method I would like to inherit from the Parent class, which seems wasteful in terms of keeping my code lean. This is especially true when there are multiple methods I'd like to inherit from Parent.
I'm also not sure (?) if instantiating the Parent class for every ChildTwo class might have some impact on performance.
What's the best way to avoid using inheritance while still avoiding code repetition as much as possible and having a minimal impact on performance?
Edit: Someone pointed out that this is a bad example, since .add_ten should probably be defined as n + 10 instead of n + self._private_var. That's a fair point, but it requires that I know how Parent is implemented, which may not always be the case. If Parent is in some external module then there's nothing I can do about it. Furthermore, if its implementation of .add_ten changes in the future, it has an impact on the Child class as well.
There are obviously no hard rules on when and when not to use inheritance. However, there are a few key things I do to help avoid issues.
I treat child classes as just extensions of the parent's logic. I therefore try to avoid overwriting objects, instead only extending them.
For example, I commonly have a parent class which receives the configs for a project. Then, any child classes can use these configs and do whatever necessary logic with them. All the configs are the same, they're not being changed, so inheritance will not cause any issues.
class Parent:
def __init__(self, name, configs):
self.name = name
self.theory = configs['theory']
self.log_file = configs['log_file']
...
class Child(Parent):
def __init__(self, name, configs):
super().__init__(name, configs)
I would not however have a method in the parent class that performed some action with the configs and then alter that method in the child classes. Despite that being perfectly acceptable python code, I find it easy to make mistakes and it adds unnecessary complexity. Why bother writing a method if you're going to constantly override it?
With multiple inheritance, if it's not something you've encountered before, it can be surprisingly easy to run into issues with "Method Resolution Order". The Diamond of Death or whatever other dramatic names it has. This occurs when multiple inheritance leads to ambiguity in how a child class should inherit from above it in the inheritance tree. For this reason I completely avoid ever making classes "siblings".
Inheritance can often scale badly. By which I mean, adding lots of logic to a pre-existing inheritance structure can cause issues. Maybe your child classes all used the parent class method in the same way but now you've a new child class which is slightly different. Ok so you can overwrite that method. But what if you begin adding more and more child classes which also need to overwrite that method? Now it makes sense to rewrite the base class method which means you need to rewrite all of the overwritten methods.
Sometimes inheritance will be instrumental in reducing repetition, other times it will be a headache for maintenance, testing and extension. As always in programming, if you find yourself writing the same thing over and over, you're doing something wrong. Knowing exactly what a class structure will be used for in the future, for me has been the best way of making sure any inheritance won't cause issues.
I would just say that your example seems a bit of a straw-man. You set up a demonstrably bad structure then dismiss inheritance as the reason for failure. If you're going to add ten, add ten, don't add some changeable variable.
Finally, while I have banged on about personal preference, be aware in the working environment, people's preferences will be drastically different to yours. You should understand how to use, extend and debug all different class structures.
My IDE keeps suggesting I convert my instance methods to static methods. I guess because I haven't referenced any self within these methods.
An example is :
class NotificationViewSet(NSViewSet):
def pre_create_processing(self, request, obj):
log.debug(" creating messages ")
# Ensure data is consistent and belongs to the sending bot.
obj['user_id'] = request.auth.owner.id
obj['bot_id'] = request.auth.id
So my question would be: do I lose anything by just ignoring the IDE suggestions, or is there more to it?
This is a matter of workflow, intentions with your design, and also a somewhat subjective decision.
First of all, you are right, your IDE suggests converting the method to a static method because the method does not use the instance. It is most likely a good idea to follow this suggestion, but you might have a few reasons to ignore it.
Possible reasons to ignore it:
The code is soon to be changed to use the instance (on the other hand, the idea of soon is subjective, so be careful)
The code is legacy and not entirely understood/known
The interface is used in a polymorphic/duck typed way (e.g. you have a collection of objects with this method and you want to call them in a uniform way, but the implementation in this class happens to not need to use the instance - which is a bit of a code smell)
The interface is specified externally and cannot be changed (this is analog to the previous reason)
The AST of the code is read/manipulated either by itself or something that uses it and expects this method to be an instance method (this again is an external dependency on the interface)
I'm sure there can be more, but failing these types of reasons I would follow the suggestion. However, if the method does not belong to the class (e.g. factory method or something similar), I would refactor it to not be part of the class.
I think that you might be mixing up some terminology - the example is not a class method. Class methods receive the class as the first argument, they do not receive the instance. In this case you have a normal instance method that is not using its instance.
If the method does not belong in the class, you can move it out of the class and make it a standard function. Otherwise, if it should be bundled as part of the class, e.g. it's a factory function, then you should probably make it a static method as this (at a minimum) serves as useful documentation to users of your class that the method is coupled to the class, but not dependent on it's state.
Making the method static also has the advantage this it can be overridden in subclasses of the class. If the method was moved outside of the class as a regular function then subclassing is not possible.
I'm hoping someone may be able to help me out with a design issue I'm dealing with. It's specifically in the game development domain, but I think it's really a broader issue that has probably been solved in an accepted way. I'm working in Python.
I have a GameObject class that holds the position of the object (and other general state attributes) and a reference to my Engine object, which holds information about the game world at large. GameObjects can be a categorized further: they can be VisibleGameObjects, PhysicalGameObjects (collidable), or both, in concrete form. For example, I could have an invisible boundary, which is physical, but does not have a visible representation.
VisibleGameObjects implement a draw() method that handles drawing functionality, delegating this through its parent's Engine reference. PhysicalGameObjects have bounding boxes, and define logic to handle collisions, also requiring access to GameObject attributes (acceleration, velocity, etc.)
The problem is, what happens when I'd like to define a concrete object that needs to inherit the behavior of both a VisibleGameObject, and a PhysicalGameObject (which both share a parent GameObject)? It's my understanding that this type of circular inheritance is a big-bad idea.
How can I refactor this to essentially bolt on the specific behaviors to a concrete child class (drawable, collidable) that depend on the state of the parent abstract class?
EDIT: My one thought was to assign them to concrete instances of GameObjects as components, favoring a has-a relationship over an is-a relationship. Even that doesn't seem so clean however; trying to check to see if an object is collidable by searching a "components" list for a collidable component doesn't seem great either.
It seems like you're looking for a trait
Unfortunately, python doesn't support traits natively, although there are multiple modules that try to implement the model.
My suggestion (unless you want to depend on the mentioned modules) would be to write abstract classes to expose the behaviour you want, but that don't inherit the main class - leaving that to a third class, which inherits both the main, and the behaviour-class.
It's probably less confusing with an example:
create a Visible abstract class that does not inherit from GameObject, and exposes all the intended behaviour/functions (as if it inherited from GameObject). Then, have VisibleGameObject inherit from both GameObject and Visible.
Obviously, you can only manage to write Visible on a dynamic language like python - otherwise the compiler would complain that it couldn't access inexistent fields.
I'm having a tricky problem in the game I'm working on. I'm using Pygame to develop it. I happen to be one of those developers who never uses the default__dict__ object variable; I always define __slots__ to clarify the variables an object can have (I have a classmethod that reads the slots to determine the variables needed from a config file).
Anyway, I just realized that this effort isn't working in some of my classes; they still have a __dict__ variable and can have arbitrary attributes assigned to, even though they explicitly define their __slots__. I think this is because they are inheriting from pygame.sprite.Sprite, which has a __dict__. If this is the case, how do I suppress creation of this dict? (I though explicitly defining __slots__ was supposed to) Or could I be mistaken about the cause? Thanks for any insight; it's hard to find information about this particular problem via searches.
The only way to suppress arbitrary attributes and the __dict__ container of them, is to use __slots__ as you are and inherit from a class that does the same. A subclass of a class that has a __dict__ will always have a __dict__. The only way around it is to not inherit from this class (but, for example, use composition instead.)