Announcement Announcement Module
Collapse
No announcement yet.
What's the aim of spring python ? Page Title Module
Move Remove Collapse
This topic is closed
X
This is a sticky topic.
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • What's the aim of spring python ?

    Perhaps, I'm stupid, or I miss something ... But there is something I don't understand.
    First of all, I regularly use spring.net with C#.net. And I really love the way to do IoC, ... in static languages !
    But for dynamic language : I don't understand the benefit of such a thing.

    IoC could easily be done in python ... like that :
    Code:
    class Albert(object):
        """albert"""
    
    class Alfred(object):
        """alfred"""
    
    classToInstanciate = "Alfred"
    o=locals()[classToInstanciate]()
    print "I am",o.__doc__
    sure, "classToInstanciate" could be read from a configfile ...
    sure, in my simple example, there is no constructor-arg / property / reference ... things (but that could be done as easily as it)
    sure, no scope or singleton feature in this too (but cout be easily done too)

    so what the aim of spring python, except to be compatible with java/.net spring ?

  • #2
    I understand your point. I have read several blog entries discussing the viability of DI in dynamic languages, including ruby and python. In fact, I'm writing a blog article to talk about this very subject which should be published soon.

    Have you looked http://springpython.webfactional.com...config-object? It shows our pure python container, which means no XML. Instead, something that is DSL-like in nature, and doesn't depend on too much reflection.
    Code:
    from springpython.config import *
    from springpython.context import *
    
    class MovieBasedApplicationContext(PythonConfig):
        def __init__(self):
            super(MovieBasedApplicationContext, self).__init__()
            
        @Object(scope.PROTOTYPE)
        def MovieLister(self):
            lister = MovieLister()
            lister.finder = self.MovieFinder()
            lister.description = self.SingletonString()
            self.logger.debug("Description = %s" % lister.description)
            return lister
        
        @Object(scope.SINGLETON)
        def MovieFinder(self):
            return ColonMovieFinder(filename="support/movies1.txt")
        
        @Object    # scope.SINGLETON is the default
        def SingletonString(self):
            return StringHolder("There should only be one copy of this string")
    This lets you stick with python and not even think about XML.

    I'm not sure if your question was more about the XML or just DI+python in general. I will assume you are asking why do we need this DI for python? First of all, the lines inside the function calls are basically what you would have written anyway. We just scooped up this creational logic, and captured it in a centralized location. The overhead is wrapping them as method calls inside this separate class called MovieBasedApplicationContext.

    There are multiple benefits to doing this. The first immediate one, is to support testing. We can tweak the creation logic for test situations, by extending this class and injecting test dummies as needed. Look at the following example where we extend the container definition, and inject a MovieFinder dummy to isolate MovieLister for test purposes. Fetching MovieLister from the container will give us an alternative configuration with minimal effort.

    Code:
    class MyTestableAppContext(MovieBasedApplicationContext):
        def __init__(self):
            super(MyTestableAppContext, self).__init__()
            
        @Object
        def MovieFinder(self):
            return MovieFinderStub()
    Another benefit is to inject AOP proxies. By having MovieBasedApplicationContext in place, I can tweak it to wrap MovieFinder by wrapping it in a service that will not be seen by the MovieLister or its caller. This lets us tap the connection between caller and callee, and put in useful services as needed, again with minimal effort.

    Code:
    from springpython.aop import *
    from springpython.config import *
    from springpython.context import *
    
    class MovieBasedApplicationContext(PythonConfig):
        def __init__(self):
            super(MovieBasedApplicationContext, self).__init__()
            
        @Object(scope.PROTOTYPE)
        def MovieLister(self):
            lister = MovieLister()
            lister.finder = self.MovieFinder()
            lister.description = self.SingletonString()
            self.logger.debug("Description = %s" % lister.description)
            return lister
        
        # By renaming the original service to this...
        def targetMovieFinder(self):
            return ColonMovieFinder(filename="support/movies1.txt")
    
        #...we can substitute a proxy that will wrap it with an interceptor
        @Object(scope.SINGLETON)
        def MovieFinder(self):
        	return ProxyFactoryObject(target=self.targetMovieFinder(), 
                                     interceptors=MyInterceptor())
        
        
        @Object    # scope.SINGLETON is the default
        def SingletonString(self):
            return StringHolder("There should only be one copy of this string")
    
    class MyInterceptor(MethodInterceptor):
        def invoke(self, invocation):
            results = "<Wrapped>" + invocation.proceed() + "</Wrapped>"
            return results
    Other benefits are the fact that we can flexibly define scopes, like PROTOTYPE or SINGLETON. I like the fact that in one place, I can see how the app is wired from a high level perspective. This acts like the blueprints to my application. With this infrastructure in place, it is easy to think about other services to offer, like remoting, security, and transactions.

    In my humble opinion, this has nothing to do with dynamic vs. static, and as I have just demonstrated this is not an XML vs. python issue either. To me, it is about the easiest way to construct the key services in your app, manage the dependencies, and make valuable adjustments as you maintain your app. I am the first to say, don't DI everything! Only DI what your TDD exposes as key injection points for your business solution. Sure it takes a little extra effort to put in this IoC container. But when used to expose the right injection points, it can save you a lot of maintenance down the road.

    Comment


    • #3
      My question was about "DI+python in general" ...

      I understand yours explanations. Sure, for AOP, springpython have got more sense.

      thanks a lot.

      Comment


      • #4
        you should have a look at the fresh "minimock"
        http://pypi.python.org/pypi?%3Aactio...&submit=search

        what a beautiful way to mock an object ...

        Comment


        • #5
          Spring Python isn't a comprehensive web framework. In the examples coded so far, I use CherryPy http://cherrypy.org as a web framework. What i do is demonstrate how the Spring way improves quality of your app, makes it easy to mix in new services, secure the app, and provide easily configurable things like transactions.

          This is isn't a one stop shop solution for your web 2.0 needs. Frankly, I gave never been satisfied with those types of solutions. I prefer a good base with the ability to add useful libraries. Spring Python is meant to provide those useful add ons. If you look at the springirc example, you can see how it nicely sews together libirc and cherrypy to form a powerful bot tool with a web site.

          Comment

          Working...
          X