TheChymera
TheChymera

Reputation: 17934

Create set of Python functions

I would like to create a number of functions which start by calling one particular function, and end by calling another.

Each function would take a different number of arguments, but they would share the first and last line. Is this possible?

To give you an example, I am trying to use this to create a set of functions which can connect to my database via sqlalchemy, add an entry to it, and exit nicely:

from sqlalchemy import create_engine
from os import path
from common_classes import *
from sqlalchemy.orm import sessionmaker

def loadSession():
    db_path = "sqlite:///" + path.expanduser("~/animal_data.db")
    engine = create_engine(db_path, echo=False)
    Session = sessionmaker(bind=engine)
    session = Session()
    Base.metadata.create_all(engine)
    return session, engine

def add_animal(id_eth, cage_eth, sex, ear_punches, id_uzh="", cage_uzh=""):
    session, engine = loadSession()
    new_animal = Animal(id_eth=id_eth, cage_eth=cage_eth, sex=sex, ear_punches=ear_punches, id_uzh=id_uzh, cage_uzh=cage_uzh)
    session.add(new_animal)
    commit_and_close(session, engine)

def add_genotype(name, zygosity):
    session, engine = loadSession()
    new_genotype = Genotype(name=name, zygosity=zygosity)
    session.add(new_animal)
    commit_and_close(session, engine)

def commit_and_close(session, engine):
    session.commit()
    session.close()
    engine.dispose()

Again, what I am trying to do is collapse add_animal() and add_genotype() (and prospectively many more functions) into a single constructor.

I have thought maybe I can use a class for this, and while I believe loadSession() could be called from __init__ I have no idea how to call the commit_and_close() function at the end - nor how to manage the variable number of arguments of every subclass...

Upvotes: 0

Views: 58

Answers (1)

poke
poke

Reputation: 388023

Instead of having add_X functions for every type X, just create a single add function that adds an object which you create on the “outside” of the funcition:

So add_animal(params…) becomes add(Animal(params…)), and add_genotype(params…) becomes add(Genotype(params…)).

That way, your add function would just look like this:

def add (obj):
    session, engine = loadSession()
    session.add(obj)
    commit_and_close(session, engine)

Then it’s up to the caller of that function to create the object, which opens up the interface and allows you to get objects from elsewhere too. E.g. something like this would be possible too then:

for animal in zoo.getAnimals():
    add(animal)

Upvotes: 2

Related Questions