30 comments

[ 3.3 ms ] story [ 77.5 ms ] thread
Not to be mean but I don't see anything interesting here, just a function that returns a dictionary with some keys that happen to be functions. Welcome to Python I guess?
Yea I have no idea why this is on the homepage. It's so mundane.
Replicating class functionality using only closures is mundane? At the very least it's cute.

I didn't realize all beginning Python programmers knew what they could do with closures.

My point is, why have a class syntax at all? It's such a mess, "self" isn't even implicit. You don't even need to declare class methods inside the class. You just have to make sure you pass self to the class method.

This seems very loosely wrapped around what I did. Except class syntax is native. Why? I just really don't care for how sloppy the python class syntax is.

/rant

Self isn't implicit by design. One of the core python philosophies is that explicit is better than implicit.
Then isn't this pattern the epitome of the philosophy?

At some point you trade an api for being explicit. Why isn't memory management explicit in python? I just don't agree with the (seemingly arbitrary) choice of making self explicit. It really does not feel like the "Python" way.

It's mundane because there's nothing special about it. Everyone knows python has dictionaries. Everyone knows python has functional features. Everyone knows you can attach functions as properties of objects.

There's really nothing new or interesting about it. Except maybe for beginners. Which is fine. Nothing wrong with being a beginner. It's just not what I expect to see on the frontpage of HackerNews.

That's almost like someone saying: look wow, 2+2 and 2*2 and 2^2 all return the same result! Sure, amusing when you realize it for the first time, but hardly interesting for anyone but a first grader.

When have you seen this pattern shown in a Python beginners tutorial? ... or anywhere? I have never seen this pattern before and for that reason it is interesting.
Why would it show in beginner tutorials?

It's just not pythonic.

> There should be one-- and preferably only one --obvious way to do it.

Not to mention that the object['field'] syntax is rather annoying.

"The only visible difference is that you cannot simply access the members using the dot syntax (cat.sayHi)."

There's also the lack of inheritance, the lack of class specific methods, isinstance and issubclass checking, the different type, no possible way to define a custom iteration method, no way to use it as a decorator or a context manager, no static methods, and probably a dozen other things I haven't thought about.

But other than that, what have the romans ever done for us?
Most of this issues could be walked around:

- For the dot syntax, all you have to do is define the __call__ method. You could do that by creating an object that encapsulates the dictionary, defines a __call__ method, and repasses the method calls to the underlying dictionary.

- For inheritance, just create another constructor function that calls the parent constructor, adds the desired methods, and returns the new function. In JavaScript, it's called parasithic inheritance.

- For the iteration method, you just have to define the __iter__ method.

- For the isinstance and issubclass method, maybe you could create new conventions (and thus reinvent the wheel)

- About static method... should we be using them anyway?

Those are just some thoughts. This alternative way of creating objects is probably useless, nevertheless fun.

You could do that by creating an object that encapsulates the dictionary, defines a __call__ method, and repasses the method calls to the underlying dictionary.

That's what a Python object is... The underlying dictionary is called __dict__.

Static methods are fantastic. I use them all the time for deserialization. Adding a .from_json() static method to create a new instance makes way more sense to me than putting one outside the class.
Don't hold me on this, just bouncing a few possible solutions:

- Inheritance: start with an empty dictionary and pass it to an "init" function. Inheritance is then just calling another "init" inside it. Allows for "multiple inheritance".

- "isinstance" and "issubclass" are mostly useful for primitive types, i.e. distinguishing between a number and a string. Also, duck typing.

- Custom iteration/use as decorator/context manager: true, it's not possible. We could amend the language to check for dictionary keys or simply use the "a.b -> a['b']" syntax sugar like javascript. Perhaps a pre-processor? Pyscript?

- Static methods: that's a loss. Fortunately we have modules, so you could just make them simple functions. If this were Java we would have problems.

- We don't have encapsulation, but again pure Python doesn't either (name mangling notwithstanding).

I don't know what you mean by "class specific methods", "the different type".

- Inheritance: You could, but I really don't see the point of this in the first place.

- isinstance/issubclass: Duck typing is good, but the ability to check if you really need to is really good to have.

When I was talking about class specific methods, I was talking about __str__, __repr__, __cmp__, __hash__, etc.

By different type I meant that this will read as a dict and not a class if you check the type.

Sure, you could reimplement a lot of these things if you made a subclass of dict, implemented a __call__ method, yadda yadda, but at that point you're basically recreating what type() already does.

I like Javascript. And I like Python. But, writing Javascript code in Python syntax is as bad as writing Java code in Python syntax. Or writing Python code in Java syntax.

If you like Javascript that much.. then write in Javascript. Just my 2c. :-)

Edit: Forgot to capitalize.

Correct me if I'm wrong, but isn't this pretty much Python 101? I don't see anything happening here that is incredibly novel. It's slightly less Pythonic than it could be, but not even that far off.
For those that didn't see, the original title of this post was "Why use classes at all in python" and not what it is now. Apparently the author thought a dictionary was as useful and could do anything a class object can.
No, I think a closure is as useful and can do anything a "class object" can...

What exactly do you think a class can do that you can't replicate in this pattern? Inheritance? Pass the parent function in. Typeof? Store a type value or get the function name reflectively.

I'd be much more interested in using Python-Style Objects in Javascript...
I thought this was something implemented using metaclasses to not have to use dictionary-style field access... (e.g., obj.field instead of obj['field'] )
I don't think you need to use metaclasses, you can just define the relevant magic methods, something like:

    class JSLikeObject(dict):
        __getattr__ = dict.__getitem__
        __setattr__ = dict.__setitem__
ETA: That gets you JavaScript-style equivalence between attribute and index lookup, but it doesn't get you JavaScript-like binding of "this". I think you could probably do that with descriptors (and maybe it would require writing a metaclass).
Look, ma, dots!

  >>> def Cat(name):
        def hello():
          print "I'm "+name
        hello.__dict__ = {
          'hello': hello,
        }
        return hello
  >>> c = Cat('snuffels')
  >>> c.hello()
  I'm snuffels
Write JS in JS, and Python in Python. :)
agreed. JS is not a language I personally want encroaching into Python.
Responses seem to think this is Python 101. I think of it more as post-OOP Python. I have never seen this pattern before, so I was interested. Gave it a shot and it worked.

My question remains, why use Python objects vs these style objects? Sure you can say this doesn't have "support" for class-related functionality natively. But just like in Javascript, most of these can be implemented anyway.

Support inheritance by passing in the parent Function/Class and copying the attributes/values. Check the type by storing type name or check the function name via reflective programming.

My point is, I can see most of the functionality of Python classes replicated without the Python class syntax. So... why is there native class syntax when I can replicate most of the functionality with just functions.

At least from a devil's advocate perspective, why should I use classes? Is memory management better? That is the only topic I can imagine mattering if there is a library for creating objects from just functions per the example.

Memory wise it's certainly much better in classes than in a naive implementation via these. Every time you create a new pseudo-class you'll be attaching all methods over and over again, eating up way more memory than the shared methods between python classes. You can get around this by defining the functions outside the class definition itself, but at that point it feels like it's defeating the purpose.
It seems to me like pre-OOP Python. I'm not a fan of overusing classes, and a lot can be accomplished in Python without them. But from one perspective, you're just reimplementing (a subset of) classes and preferring to type out the underlying dictionary instead of letting the existing syntax do it for you. So one answer is because easier to type and read.

Another answer is that you are, in fact, using classes, you're just not using the 'class' identifier and syntax (assuming you're library was fleshed out to include all the missing features that your toy example is missing). Why doesn't Python offer three different class implementations and syntax? Why did you use a dictionary in your example, instead of implementing your own key-value object with hashing functions? Why are you using Python at all, instead of writing directly machine code?