I don't understand the result of the code below. Why is the result None?
m = {(1,2):1.0, (5,4):0.5, (3,4):0.75}
print(m.clear())
result: **None**
But if I write as
m.clear()
print(m)
result : **{}**
I have other result.
print(m.clear()) prints the value returned by the call m.clear(). print m prints the object m; clearly two very different things, and so it's unsurprising that they produce different output.
The documentation for dictionary types simply says of clear:
Remove all items from the dictionary.
That's what it does. It's not documented as returning anything, while all the documentation for all the methods that do return something are explicit about what they return (usually methods that alter a collection only return None). So there's no reason to expect it to return anything.
You are printing the return value of m.clear(), which returns None. It returns None because the .clear() method clears the dictionary in place.
By convention, any method on a default Python type that alters the mutable structure in-place, returns None. The same applies to list.sort() or to set.add(), for example.
Your second sample does not print the return value of m.clear(). It prints the empty dictionary after you cleared it.
Related
I have the following code:
def test(a):
a.append(3)
test_list = [1,2]
test(test_list)
In the above code, when I pass test_list as an argument to test function, does python send the whole list object/data (which is a big byte size) or just the reference to the list (which would be much smaller since its just a pointer)?
From what I understood by looking at Python's pass by object reference, it only sends the reference, but do not know how to verify that it indeed is the case
It's passing an alias to the function; for the life of the function, or until the function intentionally rebinds a to point to something else (with a = something), the function's a is an alias to the same list bound to the caller's test_list.
The straightforward ways to confirm this are:
Print test_list after the call; if the list were actually copied, the append in the function would only affect the copy, the caller wouldn't see it. test_list will in fact have had a new element appended, so it was the same list in the function.
Print id(test_list) outside the function, and id(a) inside the function; ids are required to be unique at any given point in time, so the only way two different lists could have the same ID is if one was destroyed before the other was created; since test_list continues to exist before and after the function call, if a has the same id, it's definitionally the same list.
All function arguments are passed by reference in Python. So the a variable in the function test will refer to the same object as test_list does in the calling code. After the function returns, test_list will contain [1,2,3].
So I have a python function that is explicitly returning a value, however my unittest receives None.
Here the function is seen returning a str value:
But my unittest receives None. see validation_result
Any ideas on what is causing the return value to default to None? I am explicitly returning a value??
The code you've highlighted just tells you what the value of the constant is - NOT that it's the value being returned from the method.
Your code returns before the return VALIDATION_SUCCESS statement is invoked - look for an empty return statement, or an explicit return None (or if VALIDATION_FAILED or other constants is set to None as well).
You can use the step through / step over functionality in your debugger to find out where it returns (since you've already set a breakpoint). Set the breakpoint at the start of the method / function you're calling into, and then step through the code to find out where your assumption is wrong.
I figured out my problem.
My execute function had a #decorator method that was missing a return statement, so the decorator had the returned value I was expecting, but then not returning the wrapped function containing it, and thus it was defaulting to None.
I am using a python script to do a cypher statement that should return 0..n results. I use a foreach loop to get all values:
for column1 in results['col1']:
# do some stuff
If the Statementresult is empty, the loop will not be executed - of course. I want to check the Statementresult before. If there is no result the python script shall do something different, e. g. printing a message.
I tried to compare the statementresult with None (but its an object, even if its empty), or use the first index. I looked for a solution in the documentation and online but could not find anything. How can I check if its empty or not? Is it also possible to get e. g. the 3rd result if it exists?
Thanks!
Stefan
I found a way using the internal method peek() of class StatementResult. If you call this method it will raise an error in case there no records in the result object. I wrapped this code within a function which can be used passing the Result object to it.
def isResultRecord(results):
try:
results.peek()
except ResultError:
return False
else:
return True
if (results.peek() is None):
# empty object
I know I can add some if blocks around to avoid this problem, but I am looking for a best practice or good/nice way to handle this kind of programming problem.
I am looping through the result of a function, without storing the result first in a separate variable; something like this:
for item in mycustimitemgetter.itter():
dosomething()
The itter function is returning None instead of an empty list [], and Python throws an exception per None. This is correct python behavior and nothing's wrong with it. But I'm looking for a best practice solution to:
a) keep the code clean and simple (not storing the result in a var and do if != None, etc..)
b) treat a None return value like an empty list i.e. do not run the loop and silently ignore the fact that function returned a None value.
Perhaps, use the fact that both [] and None evaluate as False, but lists with contents don't:
for item in (mycustimitemgetter.itter() or []):
dosomething()
You have a method called itter() which returns an iterable object. I would say that given the name of the function, it's reasonable to say "the returned value should always be iterable". So, if you're returning a list, you should return an empty list if you have no values.
Code there to be executed. There is nothing wrong with adding:
if retval is None:
return []
return retval
or
return retval or []
to the end of your itter() implementation, depending on the types in use.
Consider this: you wrote the code and you're facing this problem. What about someone else who's trying to use your code without knowing what you know. What do they expect?
Alternatively you should use Generators (if suitable). They contain a 'next' method (see the docs at the link), which you can return false if there are no values.
I have a function that treats and returns data, but according to a boolean input parameter, should do a slightly different treatment (not different enough to justify a new function, I think). This slightly different treatment also requires the returning of an additional parameter.
Let's say I have this.
def func(data, special_case = False):
#Do treatment
...
if special_case:
#do some more stuff
...
#return results
if special_case:
return results, extra_results
else:
return results
Is that considered clean? Or maybe I should always return the second variable, but just make it empty when I'm not treating the special case?
#return results
if special_case:
extra_results = something
else:
extra_results = []
return results, extra_results
No, I don't think so. Now your caller has to know about your function internals, specifically that your option changes the return type. That's just another thing for the caller to remember, and is poor encapsulation.
I would either split this into two functions (preferred), or return a None placeholder, or return an object that can be introspected for additional elements. But the structure of the returned data type should not change.
Yes, you should always return the same data type.
How about a dictionary, where one of the keys always contain a value and the second is either None or the special case value:
return { 'first_var':results,
'special_var': extra_results if extra_results else None}