I would personally like to know the semantic difference between using Pass and None. I could not able to find any difference in execution.
PS: I could not able to find any similar questions in SO. If you find one, please point it out.
Thanks!
pass is a statement. As such it can be used everywhere a statement can be used to do nothing.
None is an atom and as such an expression in its simplest form. It is also a keyword and a constant value for “nothing” (the only instance of the NoneType). Since it is an expression, it is valid in every place an expression is expected.
Usually, pass is used to signify an empty function body as in the following example:
def foo():
pass
This function does nothing since its only statement is the no-operation statement pass.
Since an expression is also a valid function body, you could also write this using None:
def foo():
None
While the function will behave identically, it is a bit different since the expression (while constant) will still be evaluated (although immediately discarded).
In simple terms, None is a value that you can assign to a variable that signifies emptiness. It can be useful as a default state:
a = None
def f():
a = 5
f()
pass is a statement that is like a nop. It can be useful when you are defining function stubs, for instance:
def f():
pass
In C-like languages, you would be able to define empty functions by simply putting nothing between the braces void f() { }, but since Python uses indentation instead of braces to define blocks, you must put something in the body, and pass is the idiomatic thing to put there.
That's absolute difference between pass and None
The pass (without upper case P):
Because python be the indent base language, so if you define a new method, you should have some code after that.
def method_a():
some_thing = 1 # Have to do some thing
If not, an exception should be raised so you could use the pass keyword for hacks this problem.
def method_a():
pass # Do nothing
The None:
So very different, the None keyword has a little bit same to the null keywords from another language like Java or C. That may be the empty data or not assign data like that.
[] == None
null == None
() == None
...
Related
I'm looking at a case like this:
def parse_item(self, response):
item = MetrocItem()
def ver(string):
if string:
return string
else:
return 'null'
item['latitude'] = ver(response.xpath('//input[#id="latitude"]/#value').extract_first())
It works, but is there a better way to do this?
As #Graipher mentioned in the comments, this is certainly valid in some cases, but in your particular case, it is unnecessary. If your function depends on a local variable, then you're returning a closure that needs to be reconstructed every time you call the method. But in your case, the function is going to behave the same way every time you call the method, so it would make more sense to define it globally as a private method, or even as a lambda in your case.
ver = lambda x: x if x else 'null'
But the preferred approach would be to simply define it globally and start the name with an underscore to make the intention clear.
def _ver(string):
...
You can get rid of that function completely:
string = response.xpath('//input[#id="latitude"]/#value').extract_first()
item['latitude'] = string if string else 'null'
There are use cases for having a local function - either in a class method or other method, say if you want a closure capturing something local.
In you case you want something like a colasecing null:
e.g.
>>> s = None
>>> s or "None"
'None'
So, you can use
item['latitude'] = response.xpath('//input[#id="latitude"]#value').extract_first() or "null"
It is not bad practice, but here's an alternative.
Since this small function doesn't depend on anything in parse_item and you might want it to be constructed only once, for performance, you could do this:
def parse_item(self, response):
...
def _ver(string):
...
parse_item.ver = _ver
del _ver
and refer to it inside parse_item as parse_item.ver instead of just ver. This avoids cluttering the global namespace, even with an underscored method that Python partially hides for you.
I would have recommended the lambda expression as another alternative, but Silvio got to it first.
Also, the comments that it could be a global function, visible to all, only makes sense if there's any chance it might be used anywhere else.
Also also, you can eliminate this example completely, as doctorlove and Niklas have suggested, but I assume that you mean this as an example of more complex cases.
I guess parse_item is a method inside your class. Then you can use Python's "private" methods to make your code more readable and cleaner.
Check how to write Python "private" method and then check why it's not actually a private method. ;)
For example, I'd like to do something like: greet(,'hola'), where greet is:
def greet(person='stranger', greeting='hello')
This would help greatly for testing while writing code
Upon calling a function you can use the variable names to make it even more clear what variable will assume which value. At the same time, if defaults are provided in the function definition, skipping variables when calling the function does not raise any errors. So, in short you can just do this:
def greet(person='stranger', greeting='hello')
print('{} {}'.format(greeting, person))
return
greet(greeting='hola') # same as greet(person='stranger', greeting='hola')
# returns 'hola stranger'
Note that, as I said above this would not work if for example your function definition was like this:
def greet(person, greeting)
print('{} {}'.format(greeting, person))
return
Since in this case, Python would complain saying that it does not know what to do with person; no default is supplied..
And by the way, the problem you are describing is most likely the very reason defaults are used in the first place
Without knowing the other parameters, and only knowing that the parameter you want to change is in second position you could use the inspect module to get function signature & associated default values.
Then make a copy of the default values list and change the one at the index you want:
import inspect
def greet(person='stranger', greeting='hello'):
print(person,greeting)
argspec = inspect.getargspec(greet)
defaults = list(argspec.defaults)
defaults[1] = "hola" # change second default parameter
greet(**dict(zip(argspec.args,defaults)))
Assuming that all parameters have default values (else it shifts the lists an that fails) that prints:
stranger hola
I have a script that attempts to read the begin and end point for a subset via a binary search, these values are then used to create a slice for further processing.
I noticed that when these variables did not get set (the search returned None) the code would still run and in the end I noticed that a slice spanning from None to None works as if examining the entire list (see example below).
#! /usr/bin/env python
list = [1,2,3,4,5,6,7,8,9,10]
for x in list[None:None]:
print x
Does anyone know why the choice was made to see the list[None:None] simply as list[:], at least that's what I think that happens (correct me if I'm wrong). I personally would think that throwing a TypeError would be desirable in such a case.
Because None is the default for slice positions. You can use either None or omit the value altogether, at which point None is passed in for you.
None is the default because you can use a negative stride, at which point what the default start and end positions are changed. Compare list[0:len(list):-1] to list[None:None:-1], for example.
Python uses None for 'value not specified' throughout the standard library; this is no exception.
Note that if your class implements the object.__getitem__ hook, you'll get passed a slice() object with the start, end and stride attributes set to None as well:
>>> class Foo(object):
... def __getitem__(self, key):
... print key
...
>>> Foo()[:]
slice(None, None, None)
Since Foo() doesn't even implement a __len__ having the defaults use None is entirely logical here.
I also think that list[None:None] is interpreted as list[:]. This is handy behavior because you can do something like this:
return list[some_params.get('start'):some_params.get('end')]
If the list slicing wouldn't work with None, you would have to check if start and end were None yourself:
if some_params.get('start') and some_params.get('end'):
return list[some_params.get('start'):some_params.get('end')]
elif some_params.get('start'):
return list[some_params.get('start'):]
elif end:
return list[:some_params.get('end')]
else:
return list[:]
Fortunately this is not the case in Python :).
None is the usual representation for "parameter not given", so you can communicate the fact to a function. You will often see functions or methods declared like this
def f(p=None):
if f is None:
f = some_default_value()
I guess this makes the choice clear: Be using None you can tell the slicer to use its default values.
I am running into a problem writing recursive member functions in Python. I can't initialize the default value of a function parameter to be the same value as a member variable. I am guessing that Python doesn't support that capability as it says self isn't defined at the time I'm trying to assign the parameter. While I can code around it, the lack of function overloading in Python knocks out one obvious solution I would try.
For example, trying to recursively print a linked list I get the following code for my display function;
def display(self,head = -1):
if head == -1:
head = self.head
if not head:
return
print head,
self.display(head.link)
While this code works, it is ugly.
The main function looks like this:
def main():
l = List();
l.insert(3);
l.insert(40);
l.insert(43);
l.insert(45);
l.insert(65);
l.insert(76);
l.display()
if __name__ == "__main__":
main()
If I could set the display function parameter to default to self.head if it is called without parameters then it would look much nicer. I initially tried to create two versions of the function, one that takes two parameters and one that takes one but as I said, Python doesn't support overloading. I could pass in an argument list and check for the number of arguments but that would be pretty ugly as well (it would make it look like Perl!). The trouble is, if I put the line
head = self.head
inside the function body, it will be called during every recursive call, that's definitely not the behavior I need. None is also a valid value for the head variable so I can't pass that in as a default value. I am using -1 to basically know that I'm in the initial function call and not a recursive call. I realize I could write two functions, one driving the other but I'd rather have it all self contained in one recursive function. I'm pretty sure I'm missing some basic pythonic principle here, could someone help me out with the pythonic approach to the problem?
Thanks!
I don't really see what's wrong with your code. If you chose a falsy default value for head, you could do: head = head or self.head which is more concise.
Otherwise, this is pretty much what you have to do to handle default arguments. Alternatively, use kwargs:
def display(self,**kwargs):
head = kwargs.get("head", self.head)
if not head:
return
print head,
self.display(head=head.link) # you should always name an optional argument,
# and you must name it if **kwargs is used.
I was working with generator functions and private functions of a class. I am wondering
Why when yielding (which in my one case was by accident) in __someFunc that this function just appears not to be called from within __someGenerator. Also what is the terminology I want to use when referring to these aspects of the language?
Can the python interpreter warn of such instances?
Below is an example snippet of my scenario.
class someClass():
def __init__(self):
pass
#Copy and paste mistake where yield ended up in a regular function
def __someFunc(self):
print "hello"
#yield True #if yielding in this function it isn't called
def __someGenerator (self):
for i in range(0, 10):
self.__someFunc()
yield True
yield False
def someMethod(self):
func = self.__someGenerator()
while func.next():
print "next"
sc = someClass()
sc.someMethod()
I got burned on this and spent some time trying to figure out why a function just wasn't getting called. I finally discovered I was yielding in function I didn't want to in.
A "generator" isn't so much a language feature, as a name for functions that "yield." Yielding is pretty much always legal. There's not really any way for Python to know that you didn't "mean" to yield from some function.
This PEP http://www.python.org/dev/peps/pep-0255/ talks about generators, and may help you understand the background better.
I sympathize with your experience, but compilers can't figure out what you "meant for them to do", only what you actually told them to do.
I'll try to answer the first of your questions.
A regular function, when called like this:
val = func()
executes its inside statements until it ends or a return statement is reached. Then the return value of the function is assigned to val.
If a compiler recognizes the function to actually be a generator and not a regular function (it does that by looking for yield statements inside the function -- if there's at least one, it's a generator), the scenario when calling it the same way as above has different consequences. Upon calling func(), no code inside the function is executed, and a special <generator> value is assigned to val. Then, the first time you call val.next(), the actual statements of func are being executed until a yield or return is encountered, upon which the execution of the function stops, value yielded is returned and generator waits for another call to val.next().
That's why, in your example, function __someFunc didn't print "hello" -- its statements were not executed, because you haven't called self.__someFunc().next(), but only self.__someFunc().
Unfortunately, I'm pretty sure there's no built-in warning mechanism for programming errors like yours.
Python doesn't know whether you want to create a generator object for later iteration or call a function. But python isn't your only tool for seeing what's going on with your code. If you're using an editor or IDE that allows customized syntax highlighting, you can tell it to give the yield keyword a different color, or even a bright background, which will help you find your errors more quickly, at least. In vim, for example, you might do:
:syntax keyword Yield yield
:highlight yield ctermbg=yellow guibg=yellow ctermfg=blue guifg=blue
Those are horrendous colors, by the way. I recommend picking something better. Another option, if your editor or IDE won't cooperate, is to set up a custom rule in a code checker like pylint. An example from pylint's source tarball:
from pylint.interfaces import IRawChecker
from pylint.checkers import BaseChecker
class MyRawChecker(BaseChecker):
"""check for line continuations with '\' instead of using triple
quoted string or parenthesis
"""
__implements__ = IRawChecker
name = 'custom_raw'
msgs = {'W9901': ('use \\ for line continuation',
('Used when a \\ is used for a line continuation instead'
' of using triple quoted string or parenthesis.')),
}
options = ()
def process_module(self, stream):
"""process a module
the module's content is accessible via the stream object
"""
for (lineno, line) in enumerate(stream):
if line.rstrip().endswith('\\'):
self.add_message('W9901', line=lineno)
def register(linter):
"""required method to auto register this checker"""
linter.register_checker(MyRawChecker(linter))
The pylint manual is available here: http://www.logilab.org/card/pylint_manual
And vim's syntax documentation is here: http://www.vim.org/htmldoc/syntax.html
Because the return keyword is applicable in both generator functions and regular functions, there's nothing you could possibly check (as #Christopher mentions). The return keyword in a generator indicates that a StopIteration exception should be raised.
If you try to return with a value from within a generator (which doesn't make sense, since return just means "stop iteration"), the compiler will complain at compile-time -- this may catch some copy-and-paste mistakes:
>>> def foo():
... yield 12
... return 15
...
File "<stdin>", line 3
SyntaxError: 'return' with argument inside generator
I personally just advise against copy and paste programming. :-)
From the PEP:
Note that return means "I'm done, and have nothing interesting to
return", for both generator functions and non-generator functions.
We do this.
Generators have names with "generate" or "gen" in their name. It will have a yield statement in the body. Pretty easy to check visually, since no method is much over 20 lines of code.
Other methods don't have "gen" in their name.
Also, we do not every use __ (double underscore) names under any circumstances. 32,000 lines of code. Non __ names.
The "generator vs. non-generator" method function is entirely a design question. What did the programmer "intend" to happen. The compiler can't easily validate your intent, it can only validate what you actually typed.