Thursday, November 11, 2010

"Selfless Python"

Proof of concept of Python methods using no explicit declaration of the parameter Self.

I mean:


class A:
   __metaclass__ = Selfless
   def __init__(a , b):
      self.a = a
      self.b = b


Is made to work from this example.

One common critic to Python is the need of the explicit "self" parameter declaration on function Methods. No matter how this design is optimal in terms of internal consistency, keeping things explicit, and reducing the keyword count, people keep complaining about it.

Given the access granted to the inner workings of the Language, it is easy to arrange an alternate mechanism for class methods that could preclude the declaration of a first parameter to a method. Therefore, people who are seeing complaining could try some shots of "selfless" Python.

My approach here is just as follows: I create a metaclass that uses an alternate way to fetch function methods inside the classes. With the normal "type" metaclass - i.e. normal "new style" classes - any functions declared in a class body are substituted, at class creation time, for a descriptor. When the attribute with the function name in a class, or instance of it, is retrieved, this descriptor creates a method object that wraps the original function. (And yes, the method object is created at attribute access time). This method object, when called, prepends the "instance" object as the first parameter in the list, and forwards the call to the wrapped function.

In this "selfless" proof of concept, I change the functions in the class body for descriptor objects, but descriptors that behave differently: instead of wrapping the function in a method object, they recreate the function when the method is acessed.
A new function object is created with the same code object, the same name, the same closure, but, with a different global dictionary. The global dictionary of the original function is copied and changed to include an entry named "self" which points to the object instance. (Or "None" if the function is retrieved from the class, not from an instance).

Therefore, inside these selfless methods, the name "self" can be used without ever being declared: it will exist as a global vairable at execution time, and point to the instance. Just like the parameter self exists as a local variable and points to the instance in regular Python methods.

This should not be used in production code - it is a good proof of concept - but of course there should be lots of strange and inconsistent behavior associeated with it. One of which is the fact methods can not be used "unbounded" as one does with ordinary python methods, explicitly passing an instance object as the first parameter.


Asa final consideration, Pedro Werneck had an implementation of this "feature" before here: http://www.python.org.br/wiki/NoSelf - but unlike Werneck's example, I don't fiddle with the bytecode or anyother thing to "rebuild" the bytecode so that references to an unexisting local self variable are rewritten, and "self" is artificially inserted as a local variable at runtime. The work presented here is an order of magnitude simpler, and possibly less subject to colateral effetcs.

Nonetheless: I warn again - this is just a toy! Don't use this in "real life"!

Other than that, it works finner and in a simpler way than I expected.

# -*- coding: utf-8 -*-
from types import FunctionType

"""
Changes classes so that each method has its instances changed so
that "self" is a global variable pointing to the instance. 
"""

class SelflessDescriptor(object):
    def __init__(self, func):
        self.func = func
    def __get__(self, instance, class_):
        new_globals =  self.func.func_globals.copy()
        new_globals["self"] = instance
        new_func = FunctionType(self.func.func_code,
             new_globals, self.func.func_name,
             self.func.func_defaults,
             self.func.func_closure)
        return new_func

class Selfless(type):
    def __new__(cls, name, bases, dict_):
        for key, val in dict_.items():
            if isinstance(val, FunctionType):
                dict_[key] = SelflessDescriptor(val)
        return type(name, bases, dict_)


if __name__ == "__main__":
    __metaclass__ = Selfless

    class A:
        def __init__(a, b):
            self.a = a
            self.b = b
    
    a = A("Hello", "World!")
    print a.a, a.b

58 comments:

  1. Now you just need to extend it to act like Java does put all variables in the class into the scope, not just self - they'll really like that. ;-)

    class A:
        a = None
        b = None
        def __init__(a_, b_):
            a = a_
            b = b_

        def get_a():
            return a

    (Yuck. Having to use non-breaking spaces for spacing is definitely not a nice way to have it.)

    ReplyDelete
  2. In follow-up on that, I've got it to work, provided you don't do any assignment. Due to the required use of globals rather than locals, it can't work with locals.

    Here's the code to laugh at (won't work directly with copy and paste as I had to use nbsp - Ctrl-V 160 - to get spacing to display right).


    # -*- coding: utf-8 -*-
    from types import FunctionType

    """
    Changes classes so that each method has its instances changed so
    that "self" is a global variable pointing to the instance.
    """

    class SelflessDescriptor(object):
        def __init__(self, func):
            self.func = func
        def __get__(self, instance, class_):
            if hasattr(self, 'getting'): return self.func
            self.getting = True
            new_globals = self.func.func_globals.copy()
            new_globals["self"] = instance
            new_globals.update((i, object.__getattribute__(instance, i)) for i in dir(instance))
            new_func = FunctionType(self.func.func_code,
                 new_globals, self.func.func_name,
                 self.func.func_defaults,
                 self.func.func_closure)
            del self.getting
            return new_func

    class Selfless(type):
        def __new__(cls, name, bases, dict_):
            for key, val in dict_.items():
                if isinstance(val, FunctionType):
                    dict_[key] = SelflessDescriptor(val)
            return type(name, bases, dict_)


    if __name__ == "__main__":
        __metaclass__ = Selfless

        class A:
            def __init__(a_):
                # Unfortunately, a = [a_] would not work.
                self.a = [a_]

            def add_word(s):
                # a += [s] would not work
                a.extend([s])
        
        a = A('Hello')
        a.add_word('World!')
        print ' '.join(a.a)

    Patches welcome ;-)

    ReplyDelete
  3. Hi Chris - yes, a ++ fan, friend of mine told me that he'd like this "complete selfless" approach. After all, having "self." is so much herder to read than having those -> and "*" and "Virtual Void" all over the place. :-)

    I've been thinking on it - it could be done by declaring the variables as global inside the methods, and turning the global dictionary that is created to the method into a specialized object that would commit its changes back to the instance.

    ut I am bit afraid of doing that now that friend said he'd actually _use_ such a thing. :-)

    ReplyDelete
  4. A good blog always comes-up with new and exciting information and while reading I have feel that this blog is really have all those quality that qualify a blog to be a one.I wanted to leave a little comment to support you and wish you a good continuation. Wishing you the best of luck for all your blogging efforts read this.
    java training in chennai | java training in bangalore

    java online training | java training in pune

    java training in chennai | java training in bangalore

    ReplyDelete
  5. Thanks a lot for sharing us about this update. Hope you will not get tired on making posts as informative as this. 
    python training in pune
    python online training
    python training in OMR

    ReplyDelete
  6. I am a regular reader of your blog and being students it is great to read that your responsibilities have not prevented you from continuing your study and other activities. Love
    angularjs Training in bangalore

    angularjs Training in btm

    angularjs Training in electronic-city

    angularjs online Training

    angularjs Training in marathahalli

    ReplyDelete
  7. I simply wanted to thank you so much again. I am not sure the things that I might have gone through without the type of hints revealed by you regarding that situation.
    iosh course in chennai

    ReplyDelete
  8. Nice post. I learned some new information. Thanks for sharing.

    Article submission sites
    Technology

    ReplyDelete
  9. Great post i must say and thanks for the information. Education is definitely a sticky subject. However, is still among the leading topics of our time. I appreciate your postand look forward to more.

    ReplyDelete
  10. Hi, i have read this article , it was very useful, everything is explained in detail about. if you want to learn more about this particular topic then follow this given link : https://www.excelr.com/data-science-course-training-in-bangalore/

    ReplyDelete
  11. Hi, i have read this article , it was very useful, everything is explained in detail about. if you want to learn more about this particular topic then follow this given link :

    https://www.excelr.com/data-science-course-training-in-bangalore/

    ReplyDelete
  12. Hi, i have read this article , it was very useful, everything is explained in detail about. if you want to learn more about this particular topic then follow this given link : https://www.excelr.com/data-analytics-certification-training-course-in-bangalore/

    ReplyDelete
  13. I feel very grateful that I read this. It is very helpful and very informative and I really learned a lot from it.I feel very grateful that I read this. It is very helpful and very informative and I really learned a lot from it.Technologies

    ReplyDelete
  14. Hi, i have read this article , it was very useful, everything is explained in detail about.
    if you want to learn more about this particular topic then follow this given link : data science courses in bangalore

    ReplyDelete
  15. This is a wonderful article, Given so much info in it, These type of articles keeps the users interest in the website, and keep on sharing more ... good luck. best data science training in bangalore

    ReplyDelete
  16. This is also a very good post which I really enjoyed reading
    . It is not every day that I have the possibility to see something like this..

    ReplyDelete
  17. I have to search sites with relevant information on given topic and provide them to teacher our opinion and the article.
    Data analytics courses

    ReplyDelete
  18. In sql there developer uses to interact with the database. learning sql can be done through sql certification

    ReplyDelete
  19. Nice blog! Such a good information about data analytics and its future..
    Good post! I must say thanks for the information.
    data analytics course in mumbai
    Data analytics Interview Questions

    ReplyDelete
  20. Nice blog! Such a good information about data analytics and its future..
    Good post! I must say thanks for the information.
    data analytics course in mumbai
    Data analytics Interview Questions

    ReplyDelete
  21. Study Artificial Intelligence Course in Bangalore with ExcelR where you get a great experience and better knowledge.
    Artificial Intelligence Course

    ReplyDelete
  22. Study Data Scientist Course in Bangalore with ExcelR where you get a great experience and better knowledge.
    Data Scientist Course

    ReplyDelete
  23. A good blog always comes-up with new and exciting information and while reading I have feel that this blog is really have all those quality that qualify a blog to be a one.

    digital marketing course

    ReplyDelete
  24. This comment has been removed by the author.

    ReplyDelete
  25. Looking at your Comparision, I see the point no 35, you have mentioned BO has the Write-Back capability, where it's not at all there.thanks a lot.
    Ai & Artificial Intelligence Course in Chennai
    PHP Training in Chennai
    Ethical Hacking Course in Chennai Blue Prism Training in Chennai
    UiPath Training in Chennai

    ReplyDelete
  26. You have composed an exceptionally educational article with incredible quality substance and all around spread out focuses. I concur with you on a large number of your perspectives and you have me thinking.

    SEO services in kolkata
    Best SEO services in kolkata
    SEO company in kolkata
    Best SEO company in kolkata
    Top SEO company in kolkata
    Top SEO services in kolkata
    SEO services in India
    SEO copmany in India

    ReplyDelete
  27. I have express a few of the articles on your website now, and I really like your style of blogging. I added it to my favorite’s blog site list and will be checking back soon…
    Data Scientist Courses Super site! I am Loving it!! Will return once more, Im taking your food likewise, Thanks.

    ReplyDelete
  28. Indeed a great article! I am definitely going to bookmark it to go through it over again after work.
    SAP training in Kolkata
    SAP course in kolkata
    SAP training institute in Kolkata

    ReplyDelete
  29. So luck to come across your excellent blog. Your blog brings me a great deal of fun.. Good luck with the site. ExcelR Data Science Course In Pune

    ReplyDelete
  30. I am really enjoying reading your well written articles. It looks like you spend a lot of effort and time on your blog. I have bookmarked it and I am looking forward to reading new articles. Keep up the good work.
    Java Training in Chennai

    Java Training in Velachery

    Java Training inTambaram

    Java Training in Porur

    Java Training in Omr

    Java Training in Annanagar

    ReplyDelete
  31. I think this is a really good article. You make this information interesting and engaging. ExcelR Data Analytics Courses You give readers a lot to think about and I appreciate that kind of writing.

    ReplyDelete
  32. Thank you for taking the time and sharing this information with us. It was indeed very helpful and insightful while being straight forward and to the point.
    Python Training in chennai

    Python Course in chennai

    ReplyDelete
  33. A good blog always comes-up with new and exciting information and while reading I have feel that this blog is really have all those quality that qualify a blog to be a one.I wanted to leave a little comment to support you and wish you a good continuation. Wishing you the best of luck for all your blogging efforts read this.
    DevOps Training in Chennai

    DevOps Course in Chennai

    ReplyDelete
  34. AI Patasala highly acclaimed Python Course in the Hyderabad course is your ideal choice for a career in Python.
    Python Course with Placements in Hyderabad

    ReplyDelete
  35. What an insightful take on selfless Python! Your explanation of the concept is clear and thought-provoking. Thanks for sharing your expertise—it’s a pleasure to learn from your blog."
    Data science courses in the Netherlands

    ReplyDelete