Uważam, że czytelność i zasada KISS są najważniejszymi czynnikami w programowaniu. Dlatego używam Python :)
A oto dokładny sytuacja, którą spotykamy się bardzo często:Przejście z małych skryptów do większych aplikacji nie jest łatwe
powiedzieć, że mają ładny i czysty skrypt, który jest opakowaniem do obsługi bazy danych:
import database_schema as schema
loader = schema.Loader("sqlite:///var/database.db")
session = loader.session
def addUser(name, full_name, password):
user = schema.User(name, full_name, password)
session.add(user)
session.commit()
def listUsers():
all_users = session.query(schema.User).all()
return all_users
który jest używany tak:
import database
database.addUser("mike", "Mike Driscoll", "password")
database.listUsers()
w pewnym momencie chcę przepisać ten moduł, tak aby mógł on pracować z bazami danych na inną ścieżkę (dla testów jednostkowych, na przykład).
Jakie są więc moje opcje?
Najbardziej intuicyjną rzeczą jest dodanie zmiennej
database_path == ""
, a następnie ... co? Ustawienie go za pomocą funkcjisetPath(new_path)
, a następnie dodanie wyjątku (if database_path == "": raise SomeException
) do każdej funkcji, jest po prostu brzydkie i nie powinno być wykonywane przez nikogo.W pełni funkcjonalna klasa z ustawianiem
self._database_path
w czasie inicjalizacji.
który jest następnie używany w ten sposób:
from database import Database
database = Database("sqlite:///var/database.db")
database.addUser("mike", "Mike Driscoll", "password")
database.listUsers()
To już kolejne linie kodu niż w pierwszym przykładzie, i dodanie problemu nazewnictwa: posiadanie klasy o nazwie Database
w module database
jest głupi, nie?
przepraszam za długi czytać, tutaj moje ostatnie pytania:
- Dlaczego nie ma czegoś takiego jak
__init__
funkcje modułów, w Pythonie? - Czy brakuje mi czegoś (statyczne zmienne klasy itp.), Które może zrobić to, co chcę (stały zbiór w czasie importu) w łatwy i czysty sposób, który wciąż nie jest daleko od modułu z wieloma prostymi funkcje, które były na początku?
P.S. przepraszam za mój angielski.
Edit:
Tak, aby to jasne, jak ten kod może wyglądać w mojej wyobraźni wszechświata Python:
import database_schema as schema
def __init__(database_path):
loader = schema.Loader(database_path)
global session
session = loader.session
def addUser(name, full_name, password):
user = schema.User(name, full_name, password)
session.add(user)
session.commit()
def listUsers():
all_users = session.query(schema.User).all()
return all_users
i używane tak:
import database("sqlite:///var/database.db")
database.addUser("mike", "Mike Driscoll", "password")
database.listUsers()
Dzięki za porady, za mało reputacji, aby się uporać. Nadal nie do końca rozumiem, dlaczego niemożliwe jest posiadanie funkcji uruchamianej zaraz po zaimportowaniu modułu (patrz aktualizacja oryginalnego wpisu). I nadal uważam, że źle jest pamiętać, aby robić to ręcznie (wywołanie metody setPath), a także umieścić coś tak powtarzalnego, jak "asercja ścieżka_bazy_danych", ścieżka_do bazy danych pusta "" w każdą funkcję używającą tej zmiennej. – kolobos
@kolobos Nie mam w tej chwili tłumacza, ale czy nie jest to kod w module _wykonywany_ kiedy moduł jest importowany? Oznacza to, że twoje wewnętrzne instrukcje "__init__" będą działać globalnie. – mlvljr
@mlvljr Masz rację, wszystko na "poziomie globalnym" jest wykonywane po zaimportowaniu modułu. Pytanie tutaj brzmi: jak przekazać ścieżkę do bazy danych do modułu i jak to zrobić w najbardziej "prawidłowy" i elegancki sposób. Jak widać w mojej odpowiedzi, wydaje się, że przejście na zajęcia jest tylko drogą. – kolobos