method call problem with Python - python

So I'm learning python, and I seem to be having a consistent problem with calling setText() methods on Text objects. The process works fine when I'm in the interactive IDLE GUI, but when I save modules and then try to run them, I get:
nonetype object has no attribute setText
Do I need to assign some sort of return type to the text assignment? Why would there be different behavior from IDLE to saved modules? I've searched the site and Python documentation and was unable to turn up anything. Any help would be much appreciated.
message1 = Text(Point(50,50), "Click).draw(win)
message1.setText("")
Edited to add…
Thanks Geo, your suggestion fixed things.
Now my question is, what's the difference between...
message = Text(Point(50,50), "Click").draw(win)
… and …
message = Text(Point(50,50), "Click")
message.draw(win)
… with regards to returning something, or ensuring that the message object has a type that supports certain functions?

Perhaps the draw method is not returning anything. Try changing your code to this:
message1 = Text(Point(50,50), "Click")
message1.draw(win)
message1.setText("")

I'm not sure how to answer your second question properly..so I'll just do it as an answer here.
The reason the first does not work is because you are assigning the return value of Text.draw to message. Since it returns nothing, then message is None.
In the working code, you assign message with the type Text and initialize the object. You then call the draw method of this object, and the setText method.
In the non-working code, you are calling the draw method on a new Text object, then assigning the return of that - that is, NoneType - to message. And since None has no setText method, you get an error.
(Sorry if I have mixed up NoneType and None there)

Related

Bracket not showing as closed in Python 3

I'm just starting to learn Python 3.9 as my first language. I have been fighting with this error for a while now, and I can't figure out what the issue is.
Here's what I'm working on:
def eval_express(eqstring[0], eqstring[1], eqstring[2]):
eqstring[0], eqstring[2] = float(eqstring[0]), float(eqstring[2])
return opdict[eqstring[1]](eqstring[0], eqstring[2])
I'm receiving an error that the "(" after eval_express is not closed, but as far as I can tell it is. At first, I thought it was just a glitch, but despite numerous attempts to rewrite it, increase/decrease the number of arguments, etc. it persisted. The error cropped up after I modified the arguments from variables to list items, but I don't see why that would affect it. Can anyone provide some clarification on what the program's getting hung up on?
Thank you for your help!
You are using square brackets inside the function parameters, which is not valid. Valid code would be:
def eval_express(eqstring0, eqstring1, eqstring2):
eqstring0, eqstring2 = float(eqstring0), float(eqstring2)
return opdict[eqstring1](eqstring0, eqstring2)
although you should probably use more descriptive parameter names.
You can't use parameter[] notation when entering a parameter to a function. Instead just use parameter, or you will have to do something like.
def eval_express(eqstring):
eqstring[0], eqstring[2] = float(eqstring[0]), float(eqstring[2])
return opdict[eqstring[1]](eqstring[0], eqstring[2])
Now you have to pass an array as the function parameter.

Simple way to catch misspelled Python object attributes?

When I test/debug my Python code interactively, I'm often sidetracked by accidental mis-spellings - they make me think something is wrong with my code when there isn't.
For example, my object c has a setter for the subframe property:
c.suframe = (0,0,256,256); i = c.snap(verbose=False); print(c._last_transfer_duration); show(i*10)
I expected to get a 256x256 subframe, but because I spelled it suframe instead of subframe, I'd just created an attribute suframe and there was (unexpectedly) no effect on subframing. This was an interactive typo, not a code bug. But I had to notice the misspelling to figure that out.
Is there a simple way to get Python to complain so I notice that the misspelling, instead of silently accepting the new attribute?
(Lint won't help - this is interactive debugging, not code in a file.)
[FWIW, I'm using iPython.]

Getting an unexpected output

This is my first question ever! I'm just learning how to code in Python, so don't be to hard on me.
I wrote the following class in Python and when I call the method describe_restaurant (located in the parent class), I get this 'none' output right after the description.
I can't figure out why this is happening, and I can't get rid of this 'none' output.
Here is an image of my code:
Thank you for the help on such a lousy question!
on line 38 you call:
print(my_iceCreamStand.describeRestaurant())
the function describeRestaurant() doesn't have a return so returns None by deafault. Hence why you are seeing None printed out.
If you dont want to see the None. Simply call the function without the print:
my_iceCreamStand.describeRestaurant()

Python doesn't detect syntax error

I've been trying to sort an array of number using the sort function but I forgot to write parentheses.
arr.sort
instead of
arr.sort()
My question is why can't python detect this error and inform me like Java can?
The program kept compiling fine but because I was inputting the numbers in ascending order, the problem wouldn't show up.
arr.sort is syntactically valid. It's just not the syntax you wanted. Syntactically, arr.sort is an attribute access expression for the sort attribute of whatever arr evaluates to; semantically, when arr is a list, arr.sort evaluates to a method object for arr's sort method, so it's perfectly fine at runtime too.
It's kind of like method references in Java, but since Python is dynamically typed and has method objects, it doesn't need to go through all the functional interface and poly expression stuff Java 8 had to add to support list::sort syntax.
Syntax errors are only for outright invalid syntax.
Because it is not an error.
When you do not include () the function (or method) is not called. Instead it returns the function.
Example:
>>> str.encode
<method 'encode' of 'str' objects>
In actual practice:
import tkinter as tk
def hello():
print('hello')
tk.Frame()
a = tk.button(text="Press", command=hello)
a.pack()
tk.mainloop()
Now if you try it with command=hello() then it calls the function without you actually pressing the button.
The reason why Python can't detect this type of error is because Python is dynamically typed, whereas Java is statically typed.
When you say a = arr.sort, python assigns the function to a. Now you can do a() and it will run arr.sort. This is a totally valid thing to do in Python, and since we don't tell it ahead of time what a should be, it can't know whether you meant a to be a function or a sorted list... it just trusts you know what you're doing.
Java, on the other hand, is statically typed: You tell it ahead of time what a should be. Therefore, when you accidentally leave off parens, it says "that's a function, not a list like you said it would be".
If you use an IDE like PyCharm, it will tell you lots of warnings along these lines:
self.function shows:
Statement seems to have no effect and can be replaced with function call to have an effect
but the moment we assign it:
a = self.function it has an effect and this cannot be detected.

Is it better to assign a name to a throwaway object in Python, or not?

This is not a "why doesn't my code run" question. It is a "how / why does my code work" question. I am looking to generalize from this specific case to learn what broad rules apply to similar situations in the future.
I have done some searching (Google and StackOverflow) for this, but haven't seen anything that answers this question directly. Of course, I'm not entirely sure how best to ask this question, and may be using the wrong terms. I welcome suggested edits for the question title and labels.
I have the following function (which makes use of the requests module):
def make_session(username,password,login_url):
#The purpose of this function is to create a requests.Session object,
#update the state of the object to have all of the cookies and other
#session data necessary to act as a logged in user at a website, and
#return the session to the calling function.
new_session = requests.Session()
login_page = new_session.get(login_url)
#The function get_login_submit_page takes the previously
#created login_page, extracts the target of the login form
#submit, and returns it as a unicode string.
submit_page_URL = get_login_submit_page_URL(login_page)
payload = {u'session_name': username, u'session_password': password}
new_session.post(submit_page_URL,data=payload,allow_redirects=True)
return new_session
And what I really want to know is whether or not how I do this line matters:
new_session.post(submit_page_URL,data=payload,allow_redirects=True)
According to the requests documentation, the Session.post method returns a Response object.
However, this method also has side-effects which update the Session object. It is those side effects that I care about. I have no use for the Response object this method creates.
I have tested this code in practice, both assigning the Response to a label, and leaving it as presented above. Both options appear to work equally well for my purposes.
The actual question I am asking is: since, reasonably, whether I assign a label or not, the Requests object created by my call to Session.post falls out of scope as soon as the Session is returned to the calling function, does it matter whether I assign a label or not?
Rather, do I save any memory/processing time by not making the assignment? Do I create potential unforeseen problems for myself by not doing so?
If you are not using the return value of a call, there is little point in assigning it to a local name.
The returned response object will then not be referenced anywhere and freed two bytecodes earlier than if you assigned it to a name, and ignored that name before returning from the function.

Categories