Translating Bash function call to Python - python

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.

Related

How do I define a keyword in Python to make the command shorter?

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.

how can a python shell different out put than python idle?

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.

How should I refer to any arbitrary class attributes starting with a fixed string and differing by their ending numbers?

I am writing a Python program which uses ConfigParser to read a configuration file intended to control various aspects of the program's configuration, execution and orientation to its environment and landscape. I am using Python 2.6.6 on RHEL 6.4.
One aspect of its configuration is how many rsyslog daemons it needs to interact with, and details about each of those instances. I have chosen the format instance<#>_ to enable the user to specify any arbitrary number of instances with a consistent set of attributes to configure. An excerpt from the config file appears here:
[rsyslog]
rules_dir: /etc/rsyslog.d
instance1_enable: no
instance1_name: rsyslog-Group01
instance1_startupscript: /etc/init.d/%(instance1_name)s
instance1_conf: /etc/%(instance1_name)s
instance1_rules: %(rules_dir)s/rules-%(instance1_name)s
instance1_restart: no
instance2_enable: no
instance2_name: rsyslog-Group02
instance2_startupscript: /etc/init.d/%(instance2_name)s
instance2_conf: /etc/%(instance2_name)s
instance2_rules: %(rules_dir)s/rules-%(instance2_name)s
instance2_restart: no
I build an object called 'rsyslog' such that its attributes look like this:
rsyslog.instance2_enable="no"
rsyslog.instance2_name="rsyslog-Group02"
...etc
My problem comes when I pass the rsyslog object and an instance number to a function to have that function do operations on the instance#_rules. I call the function, for example, in this way:
list_of_rules=read_files(rsyslog,2)
The function should return a list of rules which it parses out of the rules file for instance2
/etc/rsyslog.d/rules-rsyslog-Group02
Parsing the rules is no problem when I hard code the instance:
for line in fileinput.input(rsyslog_object.instance7_rules, mode='r'):
ruleline=re_ruleline.search(line)
But how do I allow for something like the following where '' represents the instance number I passed to the function:
for line in fileinput.input(rsyslog_object.instance<instancenumber>_rules, mode='r'):
I have used the locals() and globals() functions to do variable indirection in other contexts but I am not sure how I would apply them here.
Alternately, if you can see a better, more elegant or Pythonic way to solve the problem of allowing for any arbitrary number of consecutively numbered instances which can be referred to by number in iterations easily and more Pythonicly; please explain how and also why it is a better or more Pythonic way of accomplishing the task.
I am not married to using instance if there is another way to do it. ConfigParser did not allow '.' in the configuration
I'm not sure that I completely understand the question, but isn't getattr what you want:
for line in fileinput.input(
getattr(rsyslog_object, 'instance%d_rules' % instancenumber),
mode='r'):
...

Understanding Python Attributes and Methods

I am trying to learn Python and am a bit confused about a script I am playing with. I am using Python to launch scapy. There are some conditional statements that test for certain values. My confusion is centered around how the values are checked. I hope I am using the terms attributes and methods appropriately. I am still trying to figure out the builtin features vs. what is included with scapy. I've been using Powershell mainly for the last few years so its hard to switch gears :)
tcp_connect_scan_resp = sr1(IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="S"),timeout=10)
if(str(type(tcp_connect_scan_resp))=="<type 'NoneType'>"):
Print "Closed"
elif(tcp_connect_scan_resp.haslayer(TCP)):
if(tcp_connect_scan_resp.getlayer(TCP).flags == 0x12):
The first conditional statement appears to be check for the attribute 'type'. Why would they use the Python built-in str() and type() functions in this case? If I just use type() it pulls the same value.
For the second and third conditional statements appear to be using methods built into scapy. What is the logic for including the brackets () on the outside of the statements? Again if I run them manually, I get the proper value.
The second statement, the parantheses around the expression of an if statement, is simply unnecessary and bad style.
The first statement warrants a more detailed explanation:
if(str(type(tcp_connect_scan_resp))=="<type 'NoneType'>"):
This checks if the string representation of the type that tcp_connect_scan_resp is of is equal to "". This is a bad form of type checking, used in a bad way. There are situations where type checking may be necessary, but generally you should try to avoid it in Python (see duck typing). If you must, use isinstance().
In the case of the Python builtin type None, the idiomatic way is to just write
if foo is None
Now, the reason you got the "same result" by using type() yourself, is that if you enter someting in an interactive Python shell, the interpreter represents the value for you (by calling __repr__()). Except for basic types that have literal notations, like integers, strings, or sequences, the representation of an object isn't necessarlily the same as its value (or what you would type in to recreate that same object).
So, when you do
>>> foo = type(42)
>>> foo
<type 'int'>
the interpreter prints '<type 'int'>', but the result of the call is actualy int, the built-in type for integers:
>>> type(42) == int
True
>>> type(42) == "<type 'int'>"
False
Also, consider this:
Libraries or tools written to help with a specific field of expertise are often written by experts in those fields - not necessarily experts in Python. In my opinion, you often see this in scientific libraries (matplotlib and numpy for example). This doesn't mean they're bad libraries, but they often aren't a good inspiration for Pythonic style.
Never check a type by comparing str(type(obj)) == 'ClassName'.
You should use isinstance(obj, Class), or for None you just write if obj is None.

Running a python code within a python script [duplicate]

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.

Categories