How to Use a String as a Keyword Argument

How do I use a string as a keyword argument?

d = Image.objects.filter(**{'image__endswith': "jpg"})

how to pass string into a method as a keyword argument

Perhaps pass in the named parameters using the ** operator:

params=dict()
params['hours']=2
datetime.timedelta(**params)
# datetime.timedelta(0, 7200)

Can I use a string as a named argument in python

Use the double-asterisk kwargs syntax:

td = timedelta(**{my_var: 5})

How retrieve keyword arguments from a string in python?

Why reinvent the wheel? string.Formatter has the parse() function.

>>> import string
>>> [a[1] for a in string.Formatter().parse('{foo}/{bar}')]
['foo', 'bar']

How to pass the string with whitespace as a keyword argument?

How to pass a string having whitespace characters as a keyword argument?

This is not possible, since variables (and thus keyword arguments) can't have whitespace in Python.

Source:
https://docs.python.org/3/reference/lexical_analysis.html#identifiers

 

You could use underscores:

setValue(Hello_World=3)

Or pass the kwargs as a dict:

setValue(**{'Hello World': 3})

Set keyword argument's default value as length of string

Let's categorize parameters into 3 types:

  • required (positional) parameter (like substring)
  • optional parameter (like start, end), often with None as type-less placeholder
  • parameter with default argument values (like start, end)

See also:

  • "Least Astonishment" and the Mutable Default Argument
  • Effbot/Fredrik Lundh (July 17, 2008): Default Parameter Values in Python, via Wayback archive, using None as default value

Use slicing and default for end parameter

See also the runnable demo on IDEone:

class StringUtil:

def __init__(self, s):
self.string = s


def count(self, substring, start=0, end=-1): # end index/slice: -1 for the last, instead len(self.substring) - 1
self.substring = substring
self.start = start
self.end = end
self.queue = 0
self.counter = 0

for a in self.string[start:]:
if a == self.substring[0]:
self.queue += 1
if a == self.substring[end] and self.queue != 0: # -1 for the last, instead len(self.substring) - 1
self.queue -= 1
self.counter += 1

return self.counter

sub = "o*o"
s = "Hell" + sub + " W" + sub + "rld"
cnt = StringUtil(s).count(sub)
print(f" counted '{sub}' in '{s}' times: {cnt}")

Managing keyword arguments in python strings: how to format only some arguments and keep the others unformatted

In your use case, you might consider escaping the {person} in the string:

# double brace the person_name to escape it for the first format
s = '{hello} {{person_name}}'
a = s.format(hello='hello')

# a = 'hello {person_name}'

if something:
b = a.format(person_name='Alice')
# b = 'hello Alice'
else:
b = a.format(person_name='Bob')
# b = 'hello Bob'

print(b)

With this method however you will need to follow the explicit order in which you escaped your variables. i.e. you must assign hello first and then person_name. If you need to be flexible about the order of things, I would suggest using a dict to construct the variables before passing it altogether:

# dict approach
s = '{hello} {person_name}'

# determine the first variable
d = {'hello':'hello'}
... do something
d.update({'person': 'Alice'})

# unpack the dictionary as kwargs into your format method
b = s.format(**d)

# b = 'hello Alice'

This gives you a bit more flexibility on the order of things. But you must only call .format() once all the variables are provided in your dict (at least it must have a default value), otherwise it'll still raise an error.

If you want to be more fancy and want the ability to print the field names at the absence of the variable, you can make your own wrapper function as well:

# wrapper approach
# We'll make use of regex to keep things simple and versatile
import re

def my_format(message, **kwargs):

# build a regex pattern to catch words+digits within the braces {}
pat = re.compile('{[\w\d]+}')

# build a dictionary based on the identified variables within the message provided
msg_args = {v.strip('{}'): v for v in pat.findall(message)}

# update the dictionary with provided keyword args
msg_args.update(kwargs)

# ... and of course, print it
print(message.format(**msg_args))

s = 'Why {hello} there {person}'
my_format(s, hello='hey')
# Why hey there {person}

my_format(s, person='Alice')
# Why {hello} there Alice

You can determine the default display (at the absence of a variable) you want by modifying the v in dictionary comprehension.

Are the keys of a kwargs argument to Python function guaranteed to be type string?

A keyword argument passed directly must be a valid Python identifier, and yes it will always be treated as strings. Anything else is a SyntaxError.

f(foo=1) # Works
f($=1) # Fails
f(1=1) # Fails

Although, you can also give keyword arguments through unpacking. In this case, your keyword arguments must be strings still, but they can take any format.

Let's define a dummy function to test this.

def f(**kwargs):
print(kwargs)

A keyword argument can contain a space or be a string of digits. It can even contain special characters.

f(**{"hello world": 'foo'}) # prints {'hello world': 'foo'}
f(**{"1": 'foo'}) # prints {'1': 'foo'}
f(**{"$": 'foo'}) # prints {'$': 'foo'}

A keyword argument must be a string. Anything else is a TypeError.

f(**{1: 'foo'}) # TypeError: f() keywords must be strings
f(**{b'foo': 1}) # TypeError: f() keywords must be strings

how to give object to keyword argument as key

Apparently we cannot have anything else other than strings as key type.

Check detailed answer here : Are the keys of a kwargs argument to Python function guaranteed to be type string?

Check source code here:
https://github.com/python/cpython/blob/2ec70102066fe5534f1a62e8f496d2005e1697db/Python/getargs.c#L1604

Ruby convert string to keyword argument

You can use the .to_sym method. This is ruby function method that convert string to symbol.

Or using rails own, "symbol name".parameterize.underscore.to_sym. This will convert the string to :symbol_name. This uses rails naming convention.



Related Topics



Leave a reply



Submit