Using a commandline argument to call a class method - python-3.x

Aplogies if I have the terminology all wrong; I am still learning the basics of Python. I have been unable to google this issue, probably in large part because I don't know the terminology..
So. I have built a class within a .py script with LOTS of methods/functions. To keep this remotely simple, I want to call these from a commandline argument. I have no idea how to explain it, and I can't find anhy examples, so I will try to demo it:
Take for example mute_on as the function that I want to call. I run the script with the function/method in the argument, like:
python3 ./myscript.py mute_on
I assume we'd import sys(?), define the class and the function, and create the relevant object from the class:
import sys
class TelnetAVR(PioneerDevice):
def mute_on(self, mute):
self.telnet_command("MO")
mypioneer = PioneerDevice('Pioneer AVR', '192.168.2.89', 8102, 10)
...and lastly I would like the commandline argument to call the method/function - instead of calling it explicitly like:
mypioneer.mute_volume()
..I want to use the arg (sys.argv[1]) to dynamically call the function, like:
mypioneer.{sys.argv[1]}()
Any ideas, kind people? I have been auto-referred to What is getattr() exactly and how do I use it? but I have no idea how that information can help me here.
I have tried setting cmnd = 'turn_off' and then the following failed...;
getattr(mypioneer, str(cmnd))
getattr(mypioneer, cmnd)
Thanks!

This answer seems a little basic, but I cannot complain as to its efficacy;
mypioneer = PioneerDevice('Pioneer AVR', '192.168.2.89', 8102, 10)
exp = 'mypioneer.' + sys.argv[1] + '()'
print('Executing: ' + exp )
exec(exp)
I gave up loking for a graceful answer, and simply constructed a string that I wanted to execute (exp) based on the commandline argument. Works great.. Home Assistant can use the same script to call 50 telnet controls over my Pioneer AVR.

Related

VS Code IntelliSense Doesn't Autocomplete - python - How to define a method / functions that's associated to an object manually

How do I make sure all objects inside MethodA below is known by VS Code for autocomplete to work when I open up TestCaseScript.py
So, I have this main.py that define and associate a bunch of class/object into self.
main.py will import every single other script (lets say TestCaseScript.py) and pass this self as an argument so it can be use.
And inside TestCaseScript.py, the argument is accepted as MethodA
Example main.py:
self.LibraryA = ClassA()
Result = ExecuteTestCase (self)
Example TestCaseScript.py:
def ExecuteTestCase(MethodA):
MethodA.LibraryA.FunctionInsideLibraryA(arg1 = True, arg2 = False, arg3 = 'StringA')
Side Note, I'm still a baby in python, so my general knowledge of a specific term is lacking that's why I'm having this issue, because I can't google the correct keyword. My issue is with VS Code doesn't auto complete.
Again, what I want is just for autocomplete inside VS Code to work so I can directly enter LibraryA by ctrl+click. Editing the current framework is not possible because everything work.

how can I passed my test when the programm takes no arguments and I tried to use #staticmethod before my function and nothing happend

I'm a python beginner and I tried to pass my code in the pytest and nothing happens.
And appear the TypeError: read_products() takes 0 positional arguments but 1 was given. But my read_products function doesn't take any parameters. I tried to use #staticmethod before the function and includes "self" as a parameter and nothing happened. So please, Help me! The first link is my program and the second one is my test program.
https://codeshare.io/zy7nd4
https://codeshare.io/wnqKdx
In your main file you have your function defined with zero parameters (which is what you want, if I understand correctly)
def read_products():
However, when you call it from the test file, you call it with the argument "products.csv"
def test_read_products():
...
products_dict = read_products("products.csv")
...
Maybe what you want is to call it like this
products_dict = read_products()
Also, if possible please post your code in your question instead of an external site, thanks

How to execute a code from another script and pass arguments

I have a python code try.py which has to execute another one called prova.py.
I do it as folows and it works:
exec(open("prova.py").read())
Now, I have some variables I need to pass to prova.py, and I did it as follows according to what found here: https://www.geeksforgeeks.org/exec-in-python/
var = {key:val for key, val in enumerate(lista_gp_todict)}
exec(open("prova.py").read(), var)
try.py does not give error which means the way I write exec now is still correct in terms of syntax, but in the moment this exec runs it gives error in prova.py:
NameError: name 'var' is not defined
which mean that the code prova.py which has inside the variable var does not recognise it, like it was not declared. In fact var is not declared into prova.py because if I pass it I assume it already there.
What am I doing wrong?
PS: my OS is windows
Typically you would call another script with the subprocess module.
subprocess.run() accepts an iterable of strings as arguments to be run as a separate process. You can use the arguments exactly as you would call them from command line.
subprocess.run(['python', 'prova.py', my_argument])
Since you wish to pass a dict to your script, you can do so by first serializing to json, which is just a nice way of saying "convert it to a string".
Since var is your dict you can do so like.
subprocess.run(['python', 'prova.py', json.dumps(var)])
And then deserialize or "convert back to a dict" in prova.py.
var = json.loads(sys.argv[1])
Alternatively, you could import prova.py if all you intend to use from it are functions, classes, or variables.
For example, if prova.py contains:
# prova.py
def my_func(var):
# do some stuff to var
You can then do this in your main script:
import prova
var = {key:val for key, val in enumerate(lista_gp_todict)}
prova.my_func(var)

Enter new variable as argument

I want to create a function that takes some chain of characters as an argument, and uses it as a str object.
def useless_function(argument) :
print(argument)
useless_function(banana)
--> NameError: name 'banana' is not defined
So this is what I did : I created a decorator that turns whatever I enter as argument into a str my function can print.
def decorator(f) :
def wrapper(arg_f) :
str_arg = str(arg)
f(str_arg)
return wrapper
So now I can decorate useless_function with my decorator, and useless_function(banana) will print 'banana'. And it will work with whatever it enter as an argument of useless_function.
My question is : is there a more elegant way or a simpler and faster way to do this automatic transformation into a string that can be used as an argument ?
Can you please elaborate because I don't understand what it is that you are looking for or saying.
If you mean: inside a function can you do input("variable")? Then the answer is yes. It is just essentially raw_input() from python2. The input from your keyboard will always be a str if I am not mistaken.
Update after edited post:
It is still not any more clear what you are trying to do.
At the end of the function, you do return * but I assume you know this.
I am really confused, but have you considered just doing str(argument)? As in takes_argument(str(argument))
2nd Update after 2nd edit:
I think I finally understand what you are trying to do, but I might be wrong.
Now, the problem is that def useless_function(argument) : will expect argument to be defined as a variable with some value(s). I am not aware of any other way than actually putting "argument" to tell python that what you are inserting is a string of characters rather than trying to reference some variable and its value. It is the same case as with print('something'), if I were to put print(something), python would try to look up the variable called something which you haven't defined.
Hope that makes sense.

Add additional operations to existing method which is in Python module

I have a python module which has several methods:
module.py
def a():
return "This is a method"
I want to add some additional functionality to method a by calling it from script to avoid modification in module itself.
How can I add additional operations or arguments to that module calling it from script?
For example I imported module.py in my script and in that script I add two arguments to method "a" and addition of those arguments in addition to:
return "This is a method"
Well, you cannot really change any imported methods as far as I am aware. That does not mean it is completely impossible, I just wouldn't know how.
Question is though if that is actually what you want (as I believe it is a very uncommon way of handling code and I am guessing not an advisable one)?
Could it be that what you actually want to achieve is something more like this:
module_script.py
def a(variable):
return_value = "This is a " + str(variable) + " method!"
return return_value
second_script.py
import module_script
print(module_script.a("nice"))
The output of the second script would be:
"This is a nice method!"

Resources