Python Classes Generator#

This code generator produces the Python domain model, i.e. the set of Python classes that represent the entities and relationships of a Structural model.

Let’s generate the code for the Python domain model of our Structural model example structural model example. You should create a PythonGenerator object, provide the Structural model, and use the generate method as follows:

from besser.generators.python_classes import PythonGenerator

generator: PythonGenerator = PythonGenerator(model=library_model)
generator.generate()

The classes.py file with the Python domain model (i.e., the set of classes) will be generated in the <<current_directory>>/output folder and it will look as follows.

  1from datetime import datetime, date, time
  2
  3############################################
  4# Definition of Classes
  5############################################
  6
  7class Author:
  8
  9    def __init__(self, name: str, email: str, publishes: set["Book"] = None):
 10        self.name = name
 11        self.email = email
 12        self.publishes = publishes if publishes is not None else set()
 13        
 14    @property
 15    def email(self) -> str:
 16        return self.__email
 17
 18    @email.setter
 19    def email(self, email: str):
 20        self.__email = email
 21
 22    @property
 23    def name(self) -> str:
 24        return self.__name
 25
 26    @name.setter
 27    def name(self, name: str):
 28        self.__name = name
 29
 30    @property
 31    def publishes(self):
 32        return self.__publishes
 33
 34    @publishes.setter
 35    def publishes(self, value):
 36        # Bidirectional consistency
 37        old_value = getattr(self, f"_Author__publishes", None)
 38        self.__publishes = value if value is not None else set()
 39        
 40        # Remove self from old opposite end
 41        if old_value is not None:
 42            for item in old_value:
 43                if hasattr(item, "writtenBy"):
 44                    opp_val = getattr(item, "writtenBy", None)
 45                    
 46                    if isinstance(opp_val, set):
 47                        opp_val.discard(self)
 48                    
 49        # Add self to new opposite end
 50        if value is not None:
 51            for item in value:
 52                if hasattr(item, "writtenBy"):
 53                    opp_val = getattr(item, "writtenBy", None)
 54                    
 55                    if opp_val is None:
 56                        setattr(item, "writtenBy", set([self]))
 57                    elif isinstance(opp_val, set):
 58                        opp_val.add(self)
 59                    
 60
 61class Book:
 62
 63    def __init__(self, title: str, pages: int, release: date, locatedIn: "Library" = None, writtenBy: set["Author"] = None):
 64        self.title = title
 65        self.pages = pages
 66        self.release = release
 67        self.locatedIn = locatedIn
 68        self.writtenBy = writtenBy if writtenBy is not None else set()
 69        
 70    @property
 71    def title(self) -> str:
 72        return self.__title
 73
 74    @title.setter
 75    def title(self, title: str):
 76        self.__title = title
 77
 78    @property
 79    def pages(self) -> int:
 80        return self.__pages
 81
 82    @pages.setter
 83    def pages(self, pages: int):
 84        self.__pages = pages
 85
 86    @property
 87    def release(self) -> date:
 88        return self.__release
 89
 90    @release.setter
 91    def release(self, release: date):
 92        self.__release = release
 93
 94    @property
 95    def writtenBy(self):
 96        return self.__writtenBy
 97
 98    @writtenBy.setter
 99    def writtenBy(self, value):
100        # Bidirectional consistency
101        old_value = getattr(self, f"_Book__writtenBy", None)
102        self.__writtenBy = value if value is not None else set()
103        
104        # Remove self from old opposite end
105        if old_value is not None:
106            for item in old_value:
107                if hasattr(item, "publishes"):
108                    opp_val = getattr(item, "publishes", None)
109                    
110                    if isinstance(opp_val, set):
111                        opp_val.discard(self)
112                    
113        # Add self to new opposite end
114        if value is not None:
115            for item in value:
116                if hasattr(item, "publishes"):
117                    opp_val = getattr(item, "publishes", None)
118                    
119                    if opp_val is None:
120                        setattr(item, "publishes", set([self]))
121                    elif isinstance(opp_val, set):
122                        opp_val.add(self)
123                    
124
125    @property
126    def locatedIn(self):
127        return self.__locatedIn
128
129    @locatedIn.setter
130    def locatedIn(self, value):
131        # Bidirectional consistency
132        old_value = getattr(self, f"_Book__locatedIn", None)
133        self.__locatedIn = value
134        
135        # Remove self from old opposite end
136        if old_value is not None:
137            if hasattr(old_value, "has"):
138                opp_val = getattr(old_value, "has", None)
139                if isinstance(opp_val, set):
140                    opp_val.discard(self)
141                
142        # Add self to new opposite end
143        if value is not None:
144            if hasattr(value, "has"):
145                opp_val = getattr(value, "has", None)
146                if opp_val is None:
147                    setattr(value, "has", set([self]))
148                elif isinstance(opp_val, set):
149                    opp_val.add(self)
150
151class Library:
152
153    def __init__(self, name: str, address: str, has: set["Book"] = None):
154        self.name = name
155        self.address = address
156        self.has = has if has is not None else set()
157        
158    @property
159    def address(self) -> str:
160        return self.__address
161
162    @address.setter
163    def address(self, address: str):
164        self.__address = address
165
166    @property
167    def name(self) -> str:
168        return self.__name
169
170    @name.setter
171    def name(self, name: str):
172        self.__name = name
173
174    @property
175    def has(self):
176        return self.__has
177
178    @has.setter
179    def has(self, value):
180        # Bidirectional consistency
181        old_value = getattr(self, f"_Library__has", None)
182        self.__has = value if value is not None else set()
183        
184        # Remove self from old opposite end
185        if old_value is not None:
186            for item in old_value:
187                if hasattr(item, "locatedIn"):
188                    opp_val = getattr(item, "locatedIn", None)
189                    
190                    if opp_val == self:
191                        setattr(item, "locatedIn", None)
192                    
193        # Add self to new opposite end
194        if value is not None:
195            for item in value:
196                if hasattr(item, "locatedIn"):
197                    opp_val = getattr(item, "locatedIn", None)
198                    
199                    setattr(item, "locatedIn", self)
200