I think you're asking if you can call the function like this:
count(this is my string, i) # 3
instead of like this:
count('this is my string', 'i') # 3
And the answer is that there is no way to do this. The arguments are parsed when the source code is parsed and the source code parser would have no way to disambiguate a string with commas in it from multiple input arguments.
Of course, this is just one example of parser ambiguity. If a feature like that were to be proposed, I suppose that if you were really strict in the format of the input strings (no commas, extra syntax to disambiguate strings that have variable names from strings that didn't, etc) you could probably come up with a syntax to make it work. However, remembering all of that would be much more difficult than just enclosing your strings in quotes as they're meant to be (and it would make the python parser much more cumbersome to work with). So all in all, I would think it would be a net-loss for the language for them to introduce a feature like that (though I'm just one person who isn't the BDFL so don't mistake my opinion for the opinion of someone who matters).
Answer from mgilson on Stack OverflowI think you're asking if you can call the function like this:
count(this is my string, i) # 3
instead of like this:
count('this is my string', 'i') # 3
And the answer is that there is no way to do this. The arguments are parsed when the source code is parsed and the source code parser would have no way to disambiguate a string with commas in it from multiple input arguments.
Of course, this is just one example of parser ambiguity. If a feature like that were to be proposed, I suppose that if you were really strict in the format of the input strings (no commas, extra syntax to disambiguate strings that have variable names from strings that didn't, etc) you could probably come up with a syntax to make it work. However, remembering all of that would be much more difficult than just enclosing your strings in quotes as they're meant to be (and it would make the python parser much more cumbersome to work with). So all in all, I would think it would be a net-loss for the language for them to introduce a feature like that (though I'm just one person who isn't the BDFL so don't mistake my opinion for the opinion of someone who matters).
If you want a parameter as a string or float or etc, try this:
def add(x: float, y: float):
z = x + y
return z
how to create a function takes a single argument, a string.
Python - change string into arguments and pass it to a function - Stack Overflow
Use a string to call function in Python - Stack Overflow
Passing a string to a function
Videos
I want to write a function that uses a given argument inside the same function in two ways:
as a string as a object, int or float, etc. the structure should be like this:
def func(any_given_argument): print('the "any_given_argument" value is:', any_given_argument)
Examples of desired result:
func(2) = 'the 2 value is:' 2
func(df['col1']) = "the value of df['col'] is:" value of df['col1'] series
func(2+4) = 'the value of 2+4 is:' 6
Need some help doing this because I've tried a lot but didn't succeed... thanks a lot in advance!!
This does not exactly answer your question, but maybe it helps nevertheless:
As mentioned, eval should be avoided if possible. A better way imo is to use dictionary unpacking. This is also very dynamic and less error prone.
Example:
def fullName(name = "noName", family = "noFamily"):
return name + family
functionList = {'fullName': fullName}
function = 'fullName'
parameters = {'name': 'Foo', 'family': 'Bar'}
print functionListfunction
# prints FooBar
parameters = {'name': 'Foo'}
print functionListfunction
# prints FoonoFamily
You could use eval():
myString = "fullName( name = 'Joe', family = 'Brand' )"
result = eval(myString)
Beware though, eval() is considered evil by many people.
Python always receives parameters by value, so assigning a new value to a parameter variable inside the body of a function won't affect the caller.
If the value is mutable, then mutating it inside the body of the function will affect the caller, but strings are immutable (there's no method you can call on a string that will change its contents, only return a new string).
In general, the way to approach the situation you describe is to simply return multiple values:
def foo(arg1,arg2,arg3)
arg3="new_value"
return arg1+arg2, arg3
arg3=""
_, arg3 = foo(1, 2, arg3)
If you need an immutable argument to be mutable, though, an easy workaround (that doesn't involve using global) is to wrap it in a mutable container, like a list:
def foo(arg1,arg2,arg3)
arg3[0]="new_value"
return arg1+arg2
arg3=[""]
foo(1,2,arg3)
# arg3[0] is now "new_value"
To manipulate an outside-function variable, you either have to return it, or use it as a global variable:
return
def foo(arg1, arg2, arg3):
arg3 = "new_value"
return arg1 + arg2, arg3
arg3 = ""
first_return, arg3 = foo(1, 2, arg3)
global
def foo(arg1, arg2):
global arg3
arg3 = "new_value"
return arg1 + arg2
arg3 = ""
first_return = foo(1, 2)
Use dict unpacking with **. Note that -- if fk_name is the name of a ForeignKey -- fk will not be a string, but a ForwardManyToOneDescriptor. You'd probably still want to set the attribute named fk_name:
action = Action(user=user, verb=verb, **{fk_name: fk_value})
The idea is to dynamically pass to the class creation a pair of attribute name and value, to do that, create a dictionary using the name/value attribute and pass it along using dictionary unpacking:
def create_act(user, verb, name, value):
attrs = {name: value}
action = Action(user=user, verb=verb, **attrs)
action.save()
return action
I think this question boils down to the difference between named and positional arguments.
Let's define a function foo(bar):
def foo(bar):
print(bar, "(type: " + str(type(bar)) + ")")
Now, let's run some examples:
foo(1)
# 1 (type: <class 'int'>)
This is a positional argument, it goes into the function in the order you give it.
In this case, there is only one argument, so it goes into the first position of the foo function, which is the argument bar.
foo(bar=1)
# 1 (type: <class 'int'>)
This is the named equivalent of the previous version. Instead of feeding it into the function as the n-th argument, it explicitely feeds it into the argument named bar.
foo('bar=1')
# bar=1 (type: <class 'str'>)
This is a positional argument, with the string 'bar=1'. Python doesn't care what the content of that string is, it is and stays the string with the content 'bar=1'.
I suspect what you are trying to do is to feed the function named arguments, but with the arguments defined in a dict-like structure. You can achieve that like this:
args = {'bar': 1}
foo(**args)
# 1 (type: <class 'int'>)
This way, the dict args gets taken as named arguments of that function.
Now back to the question you originally had, which is, how to use the string 'bar=1' to achieve the same result. I don't think this is easily possible. It would involve parsing the string manually, then setting up that dict of named arguments. I'm not sure what you are trying to do with it, but there must surely be a better solution than using strings for that.
What you're trying to achieve is possible in maybe bash and some other stringly typed languages, not in Python.
This is perhaps the closest you can do in Python.
var_name = 'bar'
var_value = 1
foo(**{var_name: var_value})
# equivalent to foo(bar=1)
If your code needs to be written just as it is (including the rather odd way of stringing together the ZPL code, and calling a separate script via a shell intermediary, and the avoidance of subprocess, for that matter), you can resolve your issue with a few small adjustments:
First, wrap your code string in double-quotes.
label= '"^XA'+"^FO20,20^BQ,2,3^FDQA,"+"001D4B02107A;1001000;49681207"+"^FS"+"^FO50,50"+"^ADN,36,20"+"^FD"+"MAC: "+"001D4B02107A"+"^FS"+"^FO50,150"+"^ADN,36,20"+"^FD"+"SN: "+"1001000"+"^FS"+"^FO50,250"+"^ADN,36,20"+"^FD" + "Code: "+"49681207"+"^FS"+'^XZ"'
Second, make sure you're actually calling python from the shell:
command = "python script2.py "+label
Finally, if you're concerned about special characters not being read in correctly from the command line, use unicode_escape from codecs.decode to ensure correct transmission.
See this answer for more on unicode_escape.
# contents of second script
if __name__ == "__main__":
from codecs import decode
import sys
zplString = decode(sys.argv[1], 'unicode_escape')
print(zplString)
Now the call from your first script will transmit the code correctly:
import sys
import os
sys.stdout.flush()
exitCode = os.system(str(command))
Output:
^XA^FO20,20^BQ,2,3^FDQA,001D4B02107A;1001000;49681207^FS^FO50,50^ADN,36,20^FDMAC: 001D4B02107A^FS^FO50,150^ADN,36,20^FDSN: 1001000^FS^FO50,250^ADN,36,20^FDCode: 49681207^FS^XZ
Some demo code:
import sys
if __name__ == "__main__":
for i, arg in enumerate(sys.argv):
print("{}: '{}'".format(i, arg))
when called like
python test.py ^this^is^a^test
it gives
0: 'test.py'
1: 'thisisatest'
when called like
python test.py "^this^is^a^test"
it gives
0: 'test.py'
1: '^this^is^a^test'
Solution: enclose your parameter string in double-quotes, ie
label = '"' + label + '"'