GAE, Python: How to define db object classes in only one place? - python

I have a main.py which contains class definitions for objects that are fetched from db and displayed.
I also have a scrape.py that fetches these same sorts of objects from the web, and stores them to the db.
How do I avoid having to have class definitions for these objects in both main.py and scrape.py?

Put the classes in a separate module (file) and import them in both of the other files.
models.py (new file)
class MyModel(object):
pass # Implementation here
scrape.py or main.py
from models import MyModel, SomeOtherModel
m = MyModel
m.put()

Make a seperate .py file called something like classes and variables, place all classes you use in your code in that file and call it upon startup for both files.

Related

Factory & Composite Design Patterns combo in Python & circular imports

I've built a couple projects now using the composite pattern where the objects hierarchy is built from a configuration file. My problem is that I's like to save each subclass in a separate file, to allow extensions without changing the base classes' files or having huge files. Each object once instantiated is then going to instantiate a different subclass, based on a type listed in its configuration. To do this I thought of including a factory function which will live in its own file, import all accessible subclasses, and contain a single function that will just return the appropriate subclass based on the name passed to it. The problem with this, is that each of those subclass modules, in order to use this factory, must import it. This creates a circular import situation since the factory module imports all subclasses which all import it back. How can this be avoided or is there a cleaner way to instantiate a subclass dynamically within another ?
As an example - I wrote a "Pipeline" project, useful for automation of different procedures I often need to repeat. The basic parent class is called "Block", it is inherited from to create blocks that comply with a certain interface (i.e. other projects that perform actions) and from those I inherit to blocks that actually execute specific operations. A block only needs to see the its successor in the pipeline, and does not care weather this is a single block or an entire, separate pipeline. To implement this I want each block to instantiate its successor based on the order defined in the config file that is passed along the chain. If I were to write a file that imports all implemented concrete blocks and returns whichever one requested, then I wouldn't be able to import it for use in any of the concrete blocks' modules, since they are imported into the factory one in order to be available for instantiation themselves.
You know that if you write your import statement itself inside a method or function, it will only be executed after all module-level classes and functions have been defined, right? Your circular-dependency can be fixed as simply as writing a "factory" method in the base class that will contain a from factory import factory_function statement and call it.
# basemodel.py Base file
class Base:
def factory(self, *args, **kw):
from factory import factory_function
# baseblock.py Block class hierarchy base file
from basemodel import Base
class Block(Base):
...
# blockXX.py Other block classes files:
from baseblock import Block
class SpecializedBlock31(Block):
...
# factory.py:
from block import Block
...
from block31 import Block31
...
# (or some dynamic importing using __import__ and looking at the filesystem)
def factory_function(*args, **kw):
# logic to decide which class to use
...
instance = decided_class(...)
return instance

Get all user defined classes in a file

If I have a file, say first.py, which looks like this -
class Person(object):
pass
class Dog(object):
pass
and I have a second file, second.py.
How can I get all the classes that were defined in first.py in second.py?
Perhaps I should mention that the use-case I'm trying to implement is similar to the one that happens when initializing models in Django - When I run the manage.py sql myapp command, I assume Django goes through all my models in models.py and generates an SQL query for them.
So what I'm trying to do is similar to what Django does when it takes all models defined in models.py.
How can I get all the user defined classes from a file? (Unless there's a smarter way to do what Django does)
Thanks in advance!
If you have a file first.py, in second.py, you would have to write the following code to return all the user-defined classes in first.py:
import first
from types import *
userDefinedClasses = [i for i in dir(first) if type(getattr(first, i)) is TypeType]
In your simple example, pre-defining first.py, dir(first) would return the list ['Dog', 'Person', '__builtins__', '__doc__', '__file__', '__name__', '__package__']. To prune it, you would have to use the above compressed for loop to check the type of each object in the directory of first.
This would return all objects in first with type "type", which is practically all user-defined classes.
All django-Models are subclasses of models.Model which has a meta class, that collects all model-subclasses.
In general it is not possible to get all 'user-defined' classes.

Can I use a python metaclass to keep track of subclasses in separate files?

I am new to the community. In my Django project, I have a module called "social" in which I have several files like facebook.py, and twitter.py, each with classes that are subclasses of "SocialProvider"
Example
class Facebook(SocialProvider):
Also in my social module is a file called "helper.py" which contains a SocialProviderHelper, which I would like to keep track of all SocialProvider subclasses, and generate different lists, and identifiers for them. For example.. the SocialProviderHelper could "find" Facebook and Twitter and add them to various lists like cool_providers = [] popular_providers = [] old_providers, etc, etc. The goal is to make a universal SocialProviderHelper that other areas of code can import and use... for example.. in a view I may want to get all the "popular_providers" names.. so I would import SocialProviderHelper.. and do something like
helper = SocialProviderHelper()
helper.getOldProviders()
In my SocialProviderHelper, I have:
class SocialProviderHelper(object):
_providers = SocialProvider.__subclasses__()
but
subclasses()
returns an empty list seemingly because the "providers" are defined in other files that haven't been imported, and subclasses() only maintains weak references to the class if they are "alive".
Is there any way around this ?
**The end goal is to be able to whip up another subclass of SocialProvider anywhere simply by doing..
import SocialProvider
class NewSocialNetwork(SocialProvider)
...and have the SocialProviderHelper know of its existence.**
I have tried to implement "subclasses() with a metaclass that keeps a registry of subclasses, but a similar problem persists.
This could be done with a decorator:
from SocialProvider import SocialProvider
#SocialProvider.Register
class NewSocialProvider( SocialProvider ):
pass
I've assumed SocialProvider is a superclass written by you. If so, in your superclass file, the Register helper could be defined as a class method:
class SocialProvider:
subclasses = []
#classmethod
def Register( cls, subcl ):
cls.subclasses.append( subcl )
return subcl
If not, then you could still define a function somewhere, to be used as a decorator, but it and the list it appends to would have to be defined somewhere else, separate from the SocialProvider class. You mention the problem of not-yet-imported files. There's nothing you can do to detect a class that hasn't been defined yet, so you'd have to make sure that the files with the subclass definitions are imported (e.g. via statements like import facebook etc in the ___init__.py file of your module).

two controllers in a single .py file

I've been going through the reddit code and i noticed that they sometimes have two controller classes in a single py file.
eg:
api.py
contains:
class ApiminimalController
class ApiController
I was wondering how that is done. I tried it myself but i am not getting the proper results. Whenever i add a new class i only get access to the actions defined in the class which is defined the way they mention in the docs.
eg :
paster controller <c_name>
in c_name:
class <c_name>Controller:
Can i not define another controller class?
How would i define that in the routing.py?

Laying out MVC classes in Python

I'm working on a project in Python, and I'm trying to follow a somewhat-strict MVC pattern for practice. My idea was to separate things out into packages named model, view and controller, plus have a Model, View and Controller class for each. Each package would have the supporting files for each piece.
My problem is that I want to be able to use them like:
from controller import Controller
And then in the file with the Controller class I can:
from controller.someclass import SomeClass
But if I put them in packages with the same name, I get problems. I read up about how modules work, and realized I needed to name them controller/__init__.py, model/__init__.py and view/__init__.py, but it seems weird to put them in that file, and it's kind of annoying that all of them show up gedit as __init__.py
Is there any better way of doing this? Am I going about this the right way?
I've seen some black magic in the django source that pulls classes from a base.py file into the __init__.py namespace. However I'm not sure how that's done. ( See comments for how to do this. )
From what I do know, you can do one of two things.
A -
inside bar/controller/__init__.py
import os,sys
# Make sure the interpreter knows were your files are.
sys.path.append(os.path.join(os.path.dirname(__file__),'../')
from bar.controller import Controller
from bar.model import Model
from bar.view import View
class Controller(object):
model = Model()
view = View()
And now you make bar/model/__init__.py and bar/view/__init__.py
B -
inside bar/controller/__init__.py
class Model(object):
pass
class View(object):
pass
class Controller(object):
model = Model()
view = View()
Edit:...
After reading your comment, a third option comes to mind. A package doesn't litertly translate into a module in python. I think your desired result is to create a directory structure like this:
bar/
__init__.py
controller.py
model.py
view.py
Then inside controller.py
import os,sys
from bar.controller import Controller
from bar.model import Model
from bar.view import View
class Controller(object):
model = Model()
view = View()
This was a huge hurdle for me to get coming from java. Your class file names do not have to match the class name. Think of them as a step, you step into the folder(module) and then into the file(.py) and then you import your class.(Model(object))
If I understand correctly, all you're interested in doing here is having this happen:
from controller import Controller
without having the Controller class defined in controller/__init__.py is that right?
If so, then just do this:
In controller/base.py: (notice there is a file called base.py or something else)
class Controller(BaseClass):
# define Controller here
In controller/__init__.py:
from base import Controller
Now you can have the exact syntax you are looking for.

Categories