Very basic OO: changing attribute of a method - python

I'm certain this has been asked a million times, but it's difficult to search for something when you don't know the correct terminology :(
I'm attempting (again... I've never understood OO, since I got taught it very badly 8 years ago, and avoid it as much as possible, to the horror of every other programmer I know - my mind doesn't seem wired to get it, at all) to teach myself OO and PyQt simultaneously.
I don't even know if this is logically possible, but I've got a PyQt action, which is referred to by 2 different things; one of the arguments of the action is an Icon. When the action called by one of those things, I'd like to change the icon; code snippet:
self.menu()
self.toolbar()
self.actions()
def menu(self):
self.fileMenu = QtGui.QMenu("&File", self)
self.fileMenu.addAction(self.exitAct)
def toolbar(self):
self.toolbar = self.addToolBar("Exit")
self.toolbar.addAction(self.exitAct)
def actions(self):
self.exitIcon = QtGui.QIcon('exit.png')
self.exitAct = QtGui.QAction(self.exitIcon, "&Exit", self, triggered=self.close)
In the toolbar, I'd like a different icon (exitdoor.png). The documentation for QtIcon has an addFile method, so I tried:
self.toolbar.addAction(self.exitAct)
self.exitIcon.addFile("exitdoor.png")
but this didn't work, with the error ("'QToolBar' object has no attribute 'addFile'"), and
self.exitAct.addFile("exitdoor.png")
with the error 'QAction' object has no attribute 'addFile' (I do understand why this doesn't work and what the error means).
What's my stupid mistake?! (Apart from the mistake of putting myself through the pain of continuing to try and learn OO...)

'QToolBar' object has no attribute 'addFile'
Hmm, since you called addFile on self.exitIcon, it looks like you have the wrong kind of object in the self.exitIcon variable. It seems you want it to be a QtGui.QIcon type, but instead it's a QToolBar type.
You should look at where you are making assignments to self.exitIcon.
In this case, trying to learn object-oriented programming through Python is not the easiest way. Python is a fine object-oriented language, but it does not catch your errors as immediately as other languages. When you get an error like the above, the mistake was not in that line of code, but rather in a line of code that ran a while ago. Other languages would catch the mistake even before you run your program, and point you directly at the line you need to fix. It might be worthwhile for you to practice a little basic Java to get trained in OOP by a strict teacher before you go off into the wilds of Python.

I'm not familiar with PyQt and only a beginner with Python, but I have quite a bit of experience with other OO languages (primarily C++ and Java). It looks like you need to determine what kind of object is stored in the fields exitIcon and exitAct. From there, you need to find out what attributes these objects have and find the one which you can change to get the behavior you want.
More thoughts:
Somewhere between the execution of self.exitIcon = QtGui.QIcon('exit.png') and self.exitIcon.addFile("exitdoor.png") self.exitIcon is changed to refer to a QToolBar. I suggest that you start sprinkling your code with print statements so you can trace the execution of your code and find out how this variable was changed.

After talking to some much cleverer people than me, the short answer is that what I was trying to do is seemingly impossible. Once an action has been defined, it is not possible to change any attribute of it.
At the moment, my knowledge of python isn't great enough to understand exactly why this is (or how I could have realised this from the docs), but it seems that when an action is defined, it is effectively a blackbox stored in memory, and other objects can only use, and not modify, the blackbox.
Further comments still welcome!

Related

defining object method outside its class block, any reason not to?

The following surprised me, although perhaps it shouldn't have. However, I've never seen this done elsewhere
def bar_method(self):
print( f"in Foo method bar, baz={self.baz}")
# and pages more code in the real world
class Foo(object):
def __init__(self):
self.baz = "Quux"
bar = bar_method
>>> foo = Foo()
>>> foo.bar()
in Foo method bar, baz=Quux
>>>
This follows from the definition of def which is an assignment of a function object to its name in the current context.
The great advantage, as far as I am concerned, is that I can move large method definitions outside the class body and even into a different file, and merely link them into the class with a single assignment. Instantiating the class binds them as usual.
My question is simply, why have I never seen this done before? Is there anything lurking here that might bite me? Or if it's regarded as bad style, why?
(If you are wondering about my context, it's about Django View and Form subclasses. I would dearly love to keep them short, so that the business logic behind them is easy to follow. I'd far rather that methods of only cosmetic significance were moved elsewhere).
The great advantage, as far as I am concerned, is that I can move large method definitions outside the class body and even into a different file
I personnally wouldn't consider this as "a great advantage".
My question is simply, why have I never seen this done before?
Because there are very few good reasons to do so, and a lot of good reasons to NOT do so.
Or if it's regarded as bad style, why?
Because it makes it much harder to understand what's going on, quite simply. Debugging is difficult enough, and each file you have to navigate too adds to the "mental charge".
I would dearly love to keep them short, so that the business logic behind them is easy to follow. I'd far rather that methods of only cosmetic significance were moved elsewhere
Then put the important parts at the beginning of the class statement and the cosmetic ones at the end.
Also, ask yourself whether you're doing things at the right place - as far as I'm concerned, "business logic" mainly belongs to the domain layer (models), and "cosmetic" rather suggests presentation layer (views / templates). Of course some objects (forms and views specially) are actually dealing with both business rules and presentation, but even then you can often move some of this domain part to models (which the view or form will call on) and some of this presentation part to the template layer (using filters / custom tags).
My 2 cents...
NB: sorry if the above sounds a bit patronizing - I don't know what your code looks like, so I can't tell whether you're obviously already aware of this and doing the right thing already and just trying to improve further, or you're a beginner still fighting with how to achieve proper code separation...

understanding proper python code organization [duplicate]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Much of my programming background is in Java, and I'm still doing most of my programming in Java. However, I'm starting to learn Python for some side projects at work, and I'd like to learn it as independent of my Java background as possible - i.e. I don't want to just program Java in Python. What are some things I should look out for?
A quick example - when looking through the Python tutorial, I came across the fact that defaulted mutable parameters of a function (such as a list) are persisted (remembered from call to call). This was counter-intuitive to me as a Java programmer and hard to get my head around. (See here and here if you don't understand the example.)
Someone also provided me with this list, which I found helpful, but short. Anyone have any other examples of how a Java programmer might tend to misuse Python...? Or things a Java programmer would falsely assume or have trouble understanding?
Edit: Ok, a brief overview of the reasons addressed by the article I linked to to prevent duplicates in the answers (as suggested by Bill the Lizard). (Please let me know if I make a mistake in phrasing, I've only just started with Python so I may not understand all the concepts fully. And a disclaimer - these are going to be very brief, so if you don't understand what it's getting at check out the link.)
A static method in Java does not translate to a Python classmethod
A switch statement in Java translates to a hash table in Python
Don't use XML
Getters and setters are evil (hey, I'm just quoting :) )
Code duplication is often a necessary evil in Java (e.g. method overloading), but not in Python
(And if you find this question at all interesting, check out the link anyway. :) It's quite good.)
Don't put everything into classes. Python's built-in list and dictionaries will take you far.
Don't worry about keeping one class per module. Divide modules by purpose, not by class.
Use inheritance for behavior, not interfaces. Don't create an "Animal" class for "Dog" and "Cat" to inherit from, just so you can have a generic "make_sound" method.
Just do this:
class Dog(object):
def make_sound(self):
return "woof!"
class Cat(object):
def make_sound(self):
return "meow!"
class LolCat(object):
def make_sound(self):
return "i can has cheezburger?"
The referenced article has some good advice that can easily be misquoted and misunderstood. And some bad advice.
Leave Java behind. Start fresh. "do not trust your [Java-based] instincts". Saying things are "counter-intuitive" is a bad habit in any programming discipline. When learning a new language, start fresh, and drop your habits. Your intuition must be wrong.
Languages are different. Otherwise, they'd be the same language with different syntax, and there'd be simple translators. Because there are not simple translators, there's no simple mapping. That means that intuition is unhelpful and dangerous.
"A static method in Java does not translate to a Python classmethod." This kind of thing is really limited and unhelpful. Python has a staticmethod decorator. It also has a classmethod decorator, for which Java has no equivalent.
This point, BTW, also included the much more helpful advice on not needlessly wrapping everything in a class. "The idiomatic translation of a Java static method is usually a module-level function".
The Java switch statement in Java can be implemented several ways. First, and foremost, it's usually an if elif elif elif construct. The article is unhelpful in this respect. If you're absolutely sure this is too slow (and can prove it) you can use a Python dictionary as a slightly faster mapping from value to block of code. Blindly translating switch to dictionary (without thinking) is really bad advice.
Don't use XML. Doesn't make sense when taken out of context. In context it means don't rely on XML to add flexibility. Java relies on describing stuff in XML; WSDL files, for example, repeat information that's obvious from inspecting the code. Python relies on introspection instead of restating everything in XML.
But Python has excellent XML processing libraries. Several.
Getters and setters are not required in Python they way they're required in Java. First, you have better introspection in Python, so you don't need getters and setters to help make dynamic bean objects. (For that, you use collections.namedtuple).
However, you have the property decorator which will bundle getters (and setters) into an attribute-like construct. The point is that Python prefers naked attributes; when necessary, we can bundle getters and setters to appear as if there's a simple attribute.
Also, Python has descriptor classes if properties aren't sophisticated enough.
Code duplication is often a necessary evil in Java (e.g. method overloading), but not in Python. Correct. Python uses optional arguments instead of method overloading.
The bullet point went on to talk about closure; that isn't as helpful as the simple advice to use default argument values wisely.
One thing you might be used to in Java that you won't find in Python is strict privacy. This is not so much something to look out for as it is something not to look for (I am embarrassed by how long I searched for a Python equivalent to 'private' when I started out!). Instead, Python has much more transparency and easier introspection than Java. This falls under what is sometimes described as the "we're all consenting adults here" philosophy. There are a few conventions and language mechanisms to help prevent accidental use of "unpublic" methods and so forth, but the whole mindset of information hiding is virtually absent in Python.
The biggest one I can think of is not understanding or not fully utilizing duck typing. In Java you're required to specify very explicit and detailed type information upfront. In Python typing is both dynamic and largely implicit. The philosophy is that you should be thinking about your program at a higher level than nominal types. For example, in Python, you don't use inheritance to model substitutability. Substitutability comes by default as a result of duck typing. Inheritance is only a programmer convenience for reusing implementation.
Similarly, the Pythonic idiom is "beg forgiveness, don't ask permission". Explicit typing is considered evil. Don't check whether a parameter is a certain type upfront. Just try to do whatever you need to do with the parameter. If it doesn't conform to the proper interface, it will throw a very clear exception and you will be able to find the problem very quickly. If someone passes a parameter of a type that was nominally unexpected but has the same interface as what you expected, then you've gained flexibility for free.
The most important thing, from a Java POV, is that it's perfectly ok to not make classes for everything. There are many situations where a procedural approach is simpler and shorter.
The next most important thing is that you will have to get over the notion that the type of an object controls what it may do; rather, the code controls what objects must be able to support at runtime (this is by virtue of duck-typing).
Oh, and use native lists and dicts (not customized descendants) as far as possible.
The way exceptions are treated in Python is different from
how they are treated in Java. While in Java the advice
is to use exceptions only for exceptional conditions this is not
so with Python.
In Python things like Iterator makes use of exception mechanism to signal that there are no more items.But such a design is not considered as good practice in Java.
As Alex Martelli puts in his book Python in a Nutshell
the exception mechanism with other languages (and applicable to Java)
is LBYL (Look Before You Leap) :
is to check in advance, before attempting an operation, for all circumstances that might make the operation invalid.
Where as with Python the approach is EAFP (it's easier to Ask for forgiveness than permission)
A corrollary to "Don't use classes for everything": callbacks.
The Java way for doing callbacks relies on passing objects that implement the callback interface (for example ActionListener with its actionPerformed() method). Nothing of this sort is necessary in Python, you can directly pass methods or even locally defined functions:
def handler():
print("click!")
button.onclick(handler)
Or even lambdas:
button.onclick(lambda: print("click!\n"))

Wondering whether I should just bail on using properties in python

I have been trying to use properties instead of specific setters and getters in my app. They seem more pythonic and generally make my code more readable.
More readable except for one issue: Typos.
consider the following simple example (note, my properties actually do some processing even though the examples here just set or return a simple variable)
class GotNoClass(object):
def __init__(self):
object.__init__(self)
self.__a = None
def __set_a(self, a):
self.__a = a
def __get_a(self):
return self.__a
paramName = property(__get_a, __set_a)
if __name__ == "__main__":
classy = GotNoClass()
classy.paramName = 100
print classy.paramName
classy.paranName = 200
print classy.paramName
#oops! Typo above! as seen by this line:
print classy.paranName
The output, as anyone who reads a little closely will see, is:
100
100
200
Oops. Shouldn't have been except for the fact that I made a typo - I wrote paranName (two n's) instead of paramName.
This is easy to debug in this simple example, but it has been hurting me in my larger project. Since python happily creates a new variable when I accidentally meant to use a property, I get subtle errors in my code. Errors that I am finding hard to track down at times. Even worse, I once used the same typo twice (once as I was setting and later once as I was getting) so my code appeared to be working but much later, when a different branch of code finally tried to access this property (correctly) I got the wrong value - but it took me several days before I realized that my results were just a bit off.
Now that I know that this is an issue, I am spending more time closely reading my code, but ideally I would have a way to catch this situation automatically - if I miss just one I can introduce an error that does not show up until a fair bit of time has passed...
So I am wondering, should I just switch to using good old setters and getters? Or is there some neat way to avoid this situation? Do people just rely on themselves to catch these errors manually? Alas I am not a professional programmer, just someone trying to get some stuff done here at work and I don't really know the best way to approach this.
Thanks.
P.S.
I understand that this is also one of the benefits of Python and I am not complaining about that. Just wondering whether I would be better off using explicit setters and getters.
Have you tried a static analysis tool? Here is a great thread about them.
Depending on how your code works, you could try using slots. You'll get an AttributeError exception thrown when you try to assign something that's not in slots then, which will make such typo's more obvious.
There are times when compile-time checking really saves time. You seem to have identified one such case. By accident rather than careful choice I use getters and setters, and am happy ;-)

How to remove the things I don't like about Python? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 12 years ago.
Python is a great programming language, but certain things about it just annoy the heck out of me.
As such, I:
1) wanted to find out how to remove these annoyances from the language itself, or
2) find a language that is Python-like that don't have these annoyances.
I love Python for everything except:
self: just seems stupid to me that I need to include "self" as the first parameter of a function
double-underscores: It just looks ugly and a terrible special character.
__name__ has always felt like a hack to me. Try explaining it to a novice programmer, or worse to someone who programs in perl or ruby or java for a living. Comparing the magic variable name to the magic constant ”main” feels doubly so
Blocks give me of ruby envy or smalltalk envy. I like local functions. Love them. I tolerate lambda. But I really, really would like to see a more rubyesque iterator setup where we pass a callable to the list, and the callable can be defined free-form inline. Python doesn’t really do that and so it’s less of a language lab than I might like.
Properties are unattractive, partly because of blocks being absent. I don’t really want to define a named parameter (with double-underscores, most likely) and then two named functions, and THEN declare a property. That seems like so much work for such a simple situation. It is something I will only do if all other methods fail me, or if all other methods are overriding setattr and getattr.
I do realize this might be petty annoyances, but for a language I program in daily, these small annoyances can grow to be quite large.
pypy is a complete implementation of Python in Python itself (with all of the things you consider annoyances, nevertheless a very high-level implementation language that makes altering even the core of the language itself for your own purposes easier than ever before). Download it, fork it, and edit it to fix whatever you like (be sure to eventually translate the compiler and runtime to your new non-Python language, too, of course).
If that's just too much work (whiners are rarely interested in working to fix their own complaints, no matter how easy you make such work for them), just switch to Ruby, which appears to match your tastes more closely - or find the Ruby implementation written in Ruby (I don't know how it's called, but surely such a powerful language will have one) and hack that one (to fix whatever your whines are against Ruby).
Meanwhile, at least some of your annoyances leave me quite perplexed. Take, for example, the rant about properties: I don't understand what you mean. The normal way to define a R/W property is:
#property
def thename(self):
"""add the geting-code here""
#property.set
def thename(self, value):
"""add the seting-code here""
so what the hey do you mean by
define a named parameter (with
double-underscores, most likely) and
then two named functions, and THEN
declare a property
???
I could ask equally puzzled questions about the other whines, but let's wait to see if you clarify this one first (if the clarification is of the kind "oh I didn't know about it", i.e. you're whining against a language without knowing the fundaments thereof, well, I can make a guess about what that does to your credibility, of course;-).
This is a troll, and you know the answers to your own questions:
self: Write a wrapper that does away with it and inherit from that. But it does need some name if you're going to reference the object in question, unless you just want it to just magically be present (an ugly thing indeed)...
double-underscores: don't use them. Simple. They're in no way required.
_name_: again, call it something else if you like, and inherit from that base class. I don't see what the problem here is. You still need something to provide that function.
Blocks: It sounds to me like you're trying to program ruby or java in python. You can certainly pass a callable to an iterator (and you should probably go read about generators), but defining it inline leads to serious code ugliness fast. Python makes you do it out of line so that you don't end up with half your program logic in an inline, unnamed function. I don't see what the problem here is.
Properties: I don't understand what you're saying. I certainly don't define multiple functions to use or create properties of an object in most cases.
How about trying back to the basics using UNIX bash scripts?

Protocols/Interfaces in Ruby

While coding in Ruby I did not really miss the type-orientedness of Java or C++ so far, but for some cases I think it is useful to have them. For Python there was a project PyProtocols which defined interfaces and protocols for objects. Does a similar initiative also exist for Ruby? I would like to be able to declare the expected parameters for some methods for some objects (for the entire code I find such think useless). It the method during the execution receives an unexpected input, it tries to adapt it or if it cannot, it throws an exception.
Does something similar exist for Ruby? Introducing types for a type-less language like Ruby might sound freak, but I think types are sometimes useful. Thanks for help.
Check project Ruby-Contract
Not more work is happening on it. :(
This might be interesting for the second part of your question:
Type checking in ruby

Categories

Resources