5 ms·
How do you find OOP in python awkward? Out of curiosity.
by Wickk 14y ago
How do you find OOP in python awkward? Out of curiosity.
- yen223 14y agoAll those self statements.
- DeepDuh 14y agoWhat's even worse IMO is the lack of a proper built-in 'super'. The self parameters at least serve the purpose of deciding whether a function is a class function or object function. So yeah, I agree, python's OOP is kind of awkward. I love the ease of composition though, something I use extensively even in other languages since I know python.
- masklinn 14y ago> The self parameters at least serve the purpose of deciding whether a function is a class function or object function. No, it does not.
- eru 14y agoIt doesn't do that for the interpreter / compiler. But it's a common enough idiom that the human reader can rely on it.
- aptwebapps 14y agoTo elaborate on masklinn's answer, you need to add the @classmethod decorator to get a class method instead of an instance method.
- DeepDuh 14y agoNot the one you replied to, but one thing that hits me as awkward is the default static behavior of variables. something like class Foo: bar = 1 means that bar is now a static class member (static in Java's sense). It needs to be assigned to "1" explicitly in __init__ as far as I understand. That's just unintuitive and leads to lots of boilerplate, just so that you don't need specifiers like 'static'. Sometimes the fear of verbosity gets in the way of intuitiveness.
- rdtsc 14y ago> It needs to be assigned to "1" explicitly in __init__ as far as I understand. I don't think so. You do have to assign anything to it if you want to use it as a 'static' (actually 'class' attribute). You can access bar from Foo, as in Foo.bar or from an instance of Foo as in foo=Foo(); foo.bar. What probably is confusing to you is if you assign a value bar in an instance then that gets assigned to the instance not the class. That is if you do foo.bar=100 then now foo instance has an object attribute called bar=100 that overrides Foo.bar=1. But Foo.bar still stays at 1.
- masklinn 14y ago> Not the one you replied to, but one thing that hits me as awkward is the default static behavior of variables. There's no default anything, what you wrote sets "bar = 1" on the class itself, nothing more an nothing less, just as if you'd written: Foo = type("Foo", (object,), {'bar': 1}) (in fact that's pretty much what the class statement is sugar for) If you want to set it on the instance, set it on the instance. Python's class context is a namespace like every other, you can do any computation you wish in there, and at the end the ``class`` statements collects all bindings of the namespace and sets them on the class.
- DeepDuh 14y agoWell in my case foo = Foo(); print foo.bar will print 1, so it does 'kinda' work as a default value. And that's ok, I just remembered there to be some case where it didn't behave the way I expected it to (e.g. instance member assignment overriding the content of another instance), but I wasn't able to reproduce it right now.
- rb2k_ 14y agoI always found it weird that they use len([1,2,3]) rather than [1,2,3].len (no, I don't want to call [0,1,3].__len__() . Why would I want to add all of those underscores.)
- griffindy 14y ago^ this ^ never understood why certain methods (or are they functions?) are not called on the objects. This is one of the reasons I love Ruby, everything is clearly an object.
- masklinn 14y ago> ^ this ^ never understood why certain methods (or are they functions?) are not called on the objects. Because they don't depend on a given class, they're protocols. There's no "master class" in which to put them, so they go in some sort of bastardized CLOS-like generic method instead.
- Flow 14y agoThere's no need for a super class to have a len() method. I don't get your reasoning here, Python is not a statically typed language.
- orangecat 14y agoWith duck typing, that shouldn't matter. Lots of methods in the Python standard library take "file-like objects" that have read() methods and no common superclass, and that works fine without read being a top-level function.
- rdtsc 14y agoIt is rather arbitrary yeah, but I don't mind it. Len kind of makes sense as a function.
- kami8845 14y agoreasoning by BDFL here: http://stackoverflow.com/a/237312/1188079 http://stackoverflow.com/a/237312/1188079
- nahname 14y agoAnother response from a different source. Having to include self as a method argument means that those are not methods, but static functions. This really means there isn't precisely methods at all and the whole OOP part of python appears hacked together. That part seriously turned me off when I encountered it. If there is a valid reason for this, it would go a long way in explaining away one of the major reasons I dislike python. Edit: Appears to be a bug and I cannot respond to your post 'masklinn'. Can you rework the example to include the result as 42 being an instance variable instead? Thanks.
- masklinn 14y ago> Another response from a different source. Having to include self as a method argument means that those are not methods, but static functions. This declaration makes no sense. > This really means there isn't precisely methods at all Of course there is: >>> class Foo(object): ... def bar(self): return 42 ... >>> type(Foo().bar) <type 'instancemethod'> >>> m = Foo().bar >>> m() 42 > If there is a valid reason for this, it would go a long way in explaining away one of the major reasons I dislike python. I don't know (and don't really care) if you'll consider it "a valid reason", but here's GvR's reasoning: http://neopythonic.blogspot.be/2008/10/why-explicit-self-has-to-stay.html http://neopythonic.blogspot.be/2008/10/why-explicit-self-has...
- jemfinch 14y agoFunctions don't magically become methods just because the language hid the "self" or "this" parameter. You're focusing on irrelevant details.
- nahname 14y agoIt's not that the language is hiding self/this so much as what manually passing those as variables represent. What you are saying is that you never need to call a method like this? > instance.method(instance)
- majormajor 14y ago
- calvinlough 14y agoThe code to call super is awkward. Instead of saying super(MyClass, self).foo(), I would rather just say super.foo(). Having to specify self or cls as the first argument of an instance or class method. This one is weird when you are learning Python because you don't pass in the first variable but it gets magically inserted for you. Creating a class method using a method decorator. Using a decorator to do something like this seems like a hack to me. Not having a clean way to specify what all the instance variables are outside of the constructor. People with a java background are used to putting instance variable declarations as the first thing inside a class definition. In Python, these will be static variables. This seems weird and inconsistent with the how method declarations work (methods only become class methods when a decorator is used). BTW, I like Python.
- masklinn 14y ago> The code to call super is awkward. Instead of saying super(MyClass, self).foo(), I would rather just say super.foo(). That's been changed in Python 3. Although it brings other issues. > Creating a class method using a method decorator. Using a decorator to do something like this seems like a hack to me. Why? Even more so, why is a decorator more of a hack than adding a new keyword (java) or special-casing method declaration (ruby) itself? Note that you can also create class methods without decorators if you wish to, by using a metaclass (I believe the method won't be accessible from the instance though) > This seems weird and inconsistent with the how method declarations work. It's actually very coherent: every binding created in the class scope is collected and set on the class object, as if passed as the third argument to `type`. That's it. Some objects (functions) are processed a bit more, but they still end up in the same place. > methods only become class methods when a decorator is used That's because the decorator is basically a flag to tell the attribute-resolution process to handle this method differently from the normal method-resolution process.
- regularfry 14y agoClass methods needing decorators really bugs me too. The problem goes back to explicit self. The explicit self, as currently implemented, carries no information: yes, you get to pick "self" as the instance name, but everyone picks "self" for that and There's One Way To Do It in Python anyway. If you could declare a class method like this: class Foo(object): def class_method(Foo): pass then suddenly explicit self gains a meaning (Hey! Instance method!) and class method declaration doesn't go through a completely unrelated mechanism. >> methods only become class methods when a decorator is used > That's because the decorator is basically a flag to tell the attribute-resolution process to handle this method differently from the normal method-resolution process. Do you see how that's just special-casing method declaration in a similar way to Ruby's mechanism, just relying on the programmer to drive the mechanism himself? To a not-so-casual observer it looks like Guido wasn't willing or able to change enough semantics to make a syntactic fix work for class method declaration, despite there being an obvious space in the syntax for it to fit in, so lent on a convenient implementation detail - a hack - to get the same effect with more work for the programmer. Of course, it's equally possible that he believes that class methods are a code smell and should be explicitly made ugly, which I could have a certain sympathy for, but to me the current situation just looks really inelegant.