I have a question regarding python I wrote a code in python shell that shows different output and python IDLE shows different output for the same piece of code
I try to write the same code twice on python shell then tried in IDLE.
Python v3.7
a="aster\n"
b="aster\n"
print(id(a))
print(id(b))
I expected the output should be the same for both the print statement
It's an implementation detail.
In the interactive interpreter used by IDLE, each line is parsed and compiled separately, and it isn't bothering to check for b if a str object equal to 'aster\n' is already allocated, so you get two distinct objects.
If you put this in a script, the entire script is parsed before the compiler uses the resulting AST to generate code. By parsing everything at once, the compiler can notice that the same immutable string is used in more than once place, which allows it to generate code that uses multiple references to the same underlying str object.
In general, you should only care about the output of id or the result of an is comparison if you assigned the value from one name to another your self; don't assume that two literals that look the same will share a single underlying object.
Help on built-in function id in module builtins:
id(obj, /)
Return the identity of an object.
This is guaranteed to be unique among simultaneously existing objects.
(CPython uses the object's memory address.)
As you can see id returns the memory address of the object. So even you run the same script you will get different addresses.
Related
I would like to call a function in Python like a keyword. For motivation I have following problem:
Multiple variables can be deleted at once by using the keyword del.
x1,x2=1,1
del x1,x2
However,
x1,x2=1,1
del x1,x2,x3
leads to a name error if x3 is not defined. The convenience function Del deletes multiple variables independently of their existence (see this SE post):
def Del(*d:list[str])->None:
for i in d:globals().pop(i,None)
I can now call
x1,x2=1,1
Del('x1','x2','x3')
without getting an error message about non-existence of x3. However, for my new command Del I have to use brackets and quotes whereas for del I don't need them. The reason is that Del is a function, whereas del is a keyword.
How could I define Del as a keyword to call it like Del x1,x2,x3? Of course, any other method that saves quotes or brackets is welcome.
You cannot extend the grammar of Python via Python code.
Python is a mix between an interpreted and compiled language. This means that a process or program must convert the source code into another form before it can be executed. It is this process that ultimately understands the grammar that makes up Python (including all of the keywords, statements, and other syntax).
In order to extend or change the grammar, you need to change/modify the source code of that process. This is possible, but is not something that would be easy to do (you would have to modify the C code from which the Python binary is built). Additionally, even if you were successful, you could only use the new grammar for programs run using your custom binary. Anyone else running your code would receive syntax errors.
I am trying to translate this from Bash to Python:
password=$(func_name "${configFile}" "<password" "2")
func_name and configFile have been defined earlier in the script. func_name is a function and configFile is a working directory leading to an XML file.
But I don’t know what to do with func_name in this case.
And is password and array here?
Knowing that an array in Bash is called a list in Python, I have tried this, but I am not sure:
password = [configFile, "<password", "2"]
Is this correct?
A rough translation would be:
password = func_name(configFile, "<password", "2")
But this won't necessarily work at all. Python and bash think in fundamentally different ways, and you can't really "translate" back and forth between them; you have to think differently in the two languages.
For example, bash functions don't really have return values. They can print output as they run (the output being a sequence of bytes), and return a status code (basically, whether the function succeeded or not). The bash code you have captures the output (what the function prints), treats it as a string, and stores it in the password variable.
Python functions return objects. bash has no concept of an object. Python objects can be strings... or any of a variety of built-in object types, or any type you import from a library or define yourself. My Python code here takes whatever object the function returns, and stores it in the password variable. BTW, Python functions don't have return statuses, instead they can throw errors (which is a concept bash doesn't have).
Similarly, the arguments you pass to a bash function are all strings, but in Python they're objects (which can be strings, but can also be completely different types of things).
I would strongly recommend learning the languages you're trying to use. You can't translate between them at the syntactic level, you need to translate at the conceptual level, and to do that you need to understand both languages at that level.
While using python with pyroot (a python interface to a CERN data analysis package named ROOT), I encountered the following strange behaviour:
print ROOT.TFile(fname).GetListOfKeys()
outputs None while the seemingly semantically equivalent code
f=ROOT.TFile(fname)
print f.GetListOfKeys()
outputs the expected <ROOT.THashList object ("THashList") at 0x13f0fa0>.
While this is hardly the first bug I have encountered while working with ROOT, this time I am quite puzzled that python allows this bug to happen.
I reckon that somehow, the reference count for the TFile object gets wrong in the first example, and that it gets deleted before GetListOfKeys is actually called. (After setting ROOT.TFile.__del__ to be some print command, this is indeed what happens.)
The way I see it, after ROOT.TFile(fname) gets executed, but before GetListOfKeys() is called, the pointer to the TFile object is on the stack. Therefore, the reference count should not be zero and the destructor should not be called until GetListOfKeys() returns.
Can anyone shed some light on why this happens?
On a related note, is there a way to disable python from ever deling my objects implicitly just because the reference count becomes zero? I tried gc.disable(), and it did not change the results. Is there any more elegant solution than appending the objects to some globally defined write-only list?
I was playing a bit in my python shell while learning about mutability of objects.
I found something strange:
>>> x=5.0
>>> id(x)
48840312
>>> id(5.0)
48840296
>>> x=x+3.0
>>> id(x) # why did x (now 8.0) keep the same id as 5.0?
48840296
>>> id(5.0)
36582128
>>> id(5.0)
48840344
Why is the id of 5.0 reused after the statement x=x+3.0?
Fundamentally, the answer to your question is "calling id() on numbers will give you unpredictable results". The reason for this is because unlike languages like Java, where primitives literally are their value in memory, "primitives" in Python are still objects, and no guarantee is provided that exactly the same object will be used every time, merely that a functionally equivalent one will be.
CPython caches the values of the integers from -5 to 256 for efficiency (ensuring that calls to id() will always be the same), since these are commonly used and can be effectively cached, however nothing about the language requires this to be the case, and other implementations may chose not to do so.
Whenever you write a double literal in Python, you're asking the interpreter to convert the string into a valid numerical object. If it can, Python will reuse existing objects, but if it cannot easily determine whether an object exits already, it will simply create a new one.
This is not to say that numbers in Python are mutable - they aren't. Any instance of a number, such as 5.0, in Python cannot be changed by the user after being created. However there's nothing wrong, as far as the interpreter is concerned, with constructing more than one instance of the same number.
Your specific example of the object representing x = 5.0 being reused for the value of x += 3.0 is an implementation detail. Under the covers, CPython may, if it sees fit, reuse numerical objects, both integers and floats, to avoid the costly activity of constructing a whole new object. I stress however, this is an implementation detail; it's entirely possible certain cases will not display this behavior, and CPython could at any time change its number-handling logic to no longer behave this way. You should avoid writing any code that relies on this quirk.
The alternative, as eryksun points out, is simply that you stumbled on an object being garbage collected and replaced in the same location. From the user's perspective, there's no difference between the two cases, and this serves to stress that id() should not be used on "primitives".
The Devil is in the details
PyObject* PyInt_FromLong(long ival)
Return value: New reference.
Create a new integer object with a value of ival.
The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range
you actually just get back a reference to the existing object. So it
should be possible to change the value of 1. I suspect the behaviour
of Python in this case is undefined. :-)
Note This is true only for CPython and may not apply for other Python Distribution.
This question already has answers here:
How do I execute a string containing Python code in Python?
(14 answers)
Closed 9 years ago.
I want to do following. Script has some python code as a string (saved in a variable) and is it possible to run that code ?
Well, I know one way, writing that string to a file & running it, but I don't want that. Without creating any extra file, is it possible to run it ?
Here is a example :
let's assume my python file has following content
#this is a main python file
content = ''' print 'hello!'
print 'this is from sub python code' '''
print 'from main python'
The content string has a python code & I want to run it. Is it possible ?
Hope I am clear. Thank you !
I'll say this up front: This is a terrible idea, and depending on the source of the string a serious security risk.
That disclaimer out of the way, python has an exec function that executes a string containing python code. For example:
exec("print 2+2")
Edit: I originally used eval in my answer, which is useful for evaluating individual expressions, while exec can be used for more general execution of arbitrary python code in a string.
Relevant docs:
http://docs.python.org/2/reference/simple_stmts.html#exec
http://docs.python.org/2/library/functions.html#eval
Well you could use eval:
eval(content)
And that will do what you want, however it's not recommended, especially if someone else controls the content of content - it's not too hard to hack into your system if you have eval
Did you tried with exec method as per documentation that should do
exec "print 'Hello, World!'"
Depending on the code you are trying to execute, you may use eval() or exec. There are several differences between these two options:
eval() does what it should: it evaluates an expression and returns a value, not executes code. That means you may call functions, do some arithmetic, even use list comprehensions, generators or lambdas, but not execute python statements that aren't expressions (e.g. if, for, print in Python 2; however, in Python 3 print is a function and is ok).
eval() accepts more parameters than just a string. It gets locals and globals, two dictionaries, defining the scope environment. You may make evaluation nearly (though not really) safe for untrusted strings if you fill and pass these dictionaries to eval(). Probably, you may even redefine builtins by properly setting __builtins__ in globals. http://docs.python.org/2/library/functions.html#eval
exec also accepts globals and locals. See http://docs.python.org/2/reference/simple_stmts.html#exec . And it may execute everything. And it is virtually impossible to make it even relatively safe.