Assignment in conditional not permitted in Python? - python

Why is code like
if a = "hello":
pass
invalid in Python? The a = "Hello" is just a expression whose value is the Rvalue. It's valid in most languages like C or php. Some opinions?

While Python will allow you to chain assignment,
a = b = "hello"
it will not allow you to use it in an expression,
"hi" > b = "hello" # => Syntax error
This is for safety, to keep you from accidentally using = when you meant ==

This is intentionally made illegal in python as allowing it is a huge source of error and making it illegal is a minor inconvenience.
See the Design and History FAQ
My experience in python is that this is basically right. I rarely miss not being able to do this.

Related

Is it possible to run python variable declarations from a string?

This is the behaviour I'm looking for...
"a = 2" # execute this line
print a
> 2
I know about the exec statement but I need it to work in python 2 and 3 and python 3 does not allow exec to create local variables. Is there another way around this?
EDIT: Like I said - I know that I can't use exec, the accepted answer of the supposed duplicate is saying to use exec.
I dont necessarilly think this is a good idea ...
import ast
def parse_assignment(s):
lhs,rhs = s.split("=",1)
globals()[lhs] = ast.literal_eval(rhs)
parse_assignment("hello=5")
print(hello)
parse_assignment("hello2='words'")
print(hello2)
parse_assignment("hello3=[1,'hello']")
print(hello3)
https://repl.it/repls/BiodegradableLiveProgrammer

Why are braces allowed in this Python code?

Python has never used braces to define code blocks, it relies on indentation instead; this is one of the defining features of the language. There's even a little cookie that CPython gives you to show how strongly they feel about this:
>>> from __future__ import braces
SyntaxError: not a chance
When I saw this little snippet posted to a forum (since deleted) I thought it cannot possibly work. But it does!
>>> def hi(): {
print('Hello')
}
>>> hi()
Hello
Why does this code work, when it appears to violate the language syntax?
The braces aren't defining a code block as they would in other languages - they're defining a set. The print function is being evaluated and its return value (None) is being placed in the set. Once the set is created it is immediately discarded since it isn't being assigned to anything.
There are a couple of Python syntax features that are being exploited here. First, Python allows a single-statement code block to come immediately after a :. Second, an expression is allowed to span multiple lines under certain circumstances.
This code wouldn't have worked if the body of the block were more than one line, or if an assignment or statement other than a function call were attempted.
Here's a redoing of the function to make it clearer what's happening:
>>> def hi2(): print(
{ print('Hello') }
)
>>> hi2()
Hello
{None}

Python: How does multiple assignments in a single line work?

I know that assignment is a statement in Python, i.e., it doesn't evaluate to a value unlike an expression. How does the following line of code work in Python, then? Please explain what happens internally in the Python interpreter (lexing, parsing, formation of abstract syntax tree).
# this works
spam = eggs = 'ham'
# this doesn't work. Throws SyntaxError
spam = (eggs = 'ham')
why the first line above works while the second doesn't?
It's not about operator precedence. It's a designated syntax. It cannot be "reconcilliated" by adding parenthesis.
Now for the full answer (as #Rob's comments already indicate) see here and here.

dsl in python example needed like in ruby

Am a ruby guy basically, and got into a situation where I need to make a small dsl in py as follows, I know in ruby following is doable, am looking for exactly same in py
from_a_dsl_file = "
take_this 'abc'
and_process_it
and_give_me_the_output
"
class A
def take_this abc
end
def and_process_it
end
def and_give_me_the_output
'desired'
end
end
A.new.instance_eval from_a_dsl_file
# => 'desired'
Any hints, or great to have a working example please
thanks in advance
As I understand it, in Ruby there are some tricky things you can do with function calls that don't require parentheses:
x y
In Ruby, that could be a function call where function x is called with y for the argument.
Well, in Python, we don't have those tricks; if you are calling a function, you need parentheses after the function name. So, I don't think you will have much luck trying to play games with eval() for this.
Better is just to write a parser that parses the language for you and figures out what the language is trying to do. For that, Python has a particularly good library: pyparsing
http://pyparsing.wikispaces.com/
P.S. Just doing a Google search for "Python domain specific language" finds some good links, many in StackOverflow. Here is the best one I found:
Mini-languages in Python
EDIT: Okay, you asked for an example and here you go. This is my first-ever program in PyParsing and it was pretty easy. I didn't even read the documentation; I just worked from the examples in a presentation I found on the web.
Here's the URL of the presentation: http://www.ptmcg.com/geo/python/confs/TxUnconf2008Pyparsing.html
from pyparsing import *
def give_desired_output(s):
return "desired"
TAKE_THIS = Suppress("take_this") + Suppress(Word(printables))
AND_PROC = Suppress("and_process_it")
AND_GIVE = Keyword("and_give_me_the_output")
AND_GIVE.setParseAction(give_desired_output)
LANGUAGE_LINE = TAKE_THIS | AND_PROC | AND_GIVE
LANGUAGE = ZeroOrMore(LANGUAGE_LINE)
def parse_language(text):
lst = LANGUAGE.parseString(text)
assert len(lst) == 1 # trivial language returns a single value
return lst[0]
if __name__ == "__main__":
from_a_dsl_file = \
"""
take_this 'abc'
and_process_it
and_give_me_the_output
"""
print(parse_language(from_a_dsl_file)) # prints the word: desired
Sounds like you might want to look at exec() and/or execfile() (and specifically things like the ability to specify the globals and locals available).
(There's also eval(), but it only allows for a single expression, rather than a series of commands.)

Why does python disallow usage of hyphens within function and variable names?

I have always wondered why can't we use hyphens in between function names and variable names in python
Having tried functional programming languages like Lisp and Clojure, where hyphens are allowed. Why python doesn't do that.
# This won't work -- SyntaxError
def is-even(num):
return num % 2
# This will work
def is_even(num):
return num % 2
I am sure Sir Guido must have done this because of some reasons. I googled but couldn't manage to find the answer. Can anyone please throw some light on this?
Because hyphen is used as the subtraction operator. Imagine that you could have an is-even function, and then you had code like this:
my_var = is-even(another_var)
Is is-even(another_var) a call to the function is-even, or is it subtracting the result of the function even from a variable named is?
Lisp dialects don't have this problem, since they use prefix notation. For example, there's clear difference between
(is-even 4)
and
(- is (even 4))
in Lisps.
Because Python uses infix notation to represent calculations and a hyphen and a minus has the exact same ascii code. You can have ambiguous cases such as:
a-b = 10
a = 1
b = 1
c = a-b
What is the answer? 0 or 10?
Because it would make the parser even more complicated. It would be confusing too for the programmers.
Consider def is-even(num): : now, if is is a global variable, what happens?
Also note that the - is the subtraction operator in Python, hence would further complicate parsing.
is-even(num)
contains a hyphen ? I thought it was a subtraction of the value returned by function even with argument num from the value of is.
As #jdupont says, parsing can be tricky.
Oddly enough it is possible to have class variable names with hyphens using setattr(), not that you would want to. Here is an example:
class testclass:
pass
x = testclass()
setattr(x, "is-even", True)
getattr(x, "is-even")
True
This still fails:
x.is-even
File "<stdin>", line 1
x.is-even
^
SyntaxError: invalid syntax

Categories