Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can PyCharm automatically generate __eq__() and __hash__() implementations?

Tags:

I am a PyCharm newbie but a long-time IntelliJ user. In IntelliJ, when you are writing a class definition, the IDE can automatically generate a constructor, equals() method, and hashCode() method based on the instance variables. This is good not just for saving typing, but for preventing inadvertent errors and for automatically throwing in some equals() and hashCode() best practices.

I was hoping PyCharm could do the same, given that the products are from the same company. After much Googling and scouring of the documentation, I couldn't find anything for __eq__() or __hash__(). Granted, Python instance variables are not explicitly specified, but I was hoping the generator could follow a convention like offering all __init()__ parameters as potential instance variables. As for __init__(), I found something that will automatically add instance variable settings into the __init__(), but this approach seems more cumbersome than just typing, and it doesn't even add the instance variables as parameters to the __init__() signature.

Am I missing anything in the documentation, or perhaps there is a plugin that can do this?

Update: to be clear, I am looking for something that generates the actual implementations of these methods. That is, if I had a class called Point, and PyCharm knows my class has x and y instance variables, then it would automatically generate this for the __eq__() method:

def __eq__(self, other):     if not isinstance(other, Point):         return NotImplemented     elif self is other:         return True     else:         return self.x == other.x and self.y == other.y 

The equivalent is easily done in IntelliJ.

like image 925
sparc_spread Avatar asked May 20 '15 15:05

sparc_spread


2 Answers

You can create a Live Template

Under File->Settings->Editor->Live Templates Look for Python Click + to add, I then name mine "class" and make sure to add a context in the gui for Python files.

The Template Text :

class $class_name$:     """$class_docstring$"""      def __init__(self, $args$):         """$init_docstring$"""         pass      def __eq__(self, $other$):         if not isinstance($other$, $class_name$):             return NotImplemented         elif self is $other$:             return True         else:             return self.$eq_field$ == $other$.$eq_field$      def __hash__(self, ):         pass     $END$ 

I left my "Options" -> "Expand with" section set to "Default (Tab)" After this point, when you type "class" you can use Tab auto-complete to insert the live template. Your cursor will be bounced into any section included as a variable in the Live Template Text.

More complicated, i.e. list type, variables don't appear to be supported by LiveTemplate. For instance, conditionals in the live template text, or list expansions, don't appear to be available.

like image 121
OYRM Avatar answered Oct 11 '22 23:10

OYRM


Maybe the concept of data classes may also be interesting to you?

https://docs.python.org/3/library/dataclasses.html

Here's the example from the documentation:

from dataclasses import dataclass  @dataclass class InventoryItem:     """Class for keeping track of an item in inventory."""     name: str     unit_price: float     quantity_on_hand: int = 0      def total_cost(self) -> float:         return self.unit_price * self.quantity_on_hand 

The annotation implicitly generates default methods from the annotated types on the class. I know this is not an answer to your question (because one can not actually see the generated code) but could possibly help with the reason why you are asking.

like image 35
lfnnx Avatar answered Oct 11 '22 23:10

lfnnx