I am using Python 3.9 and trying to write the function
def greet(request, name):
return HttpResponse(f'Hello, {name.capitalize}!')
Using f to format the string but it is not working. Any ideas on why?
capitalize is a method of the str object.
Therefore you need to add parenthesis for it to be called:
def greet(request, name):
return HttpResponse(f'Hello, {name.capitalize()}!')
Furthermore, name.capitalize is really just the reference to the function.
Try running the following inside a python interpreter:
print(str.capitalize)
You could even return this function:
def cap_str(string):
return string.capitalize
s = "programming in python"
capitalize_s = cap_str(s)
s_cap = capitalize_s()
print(s_cap)
I don't know how this would be particularly useful, but returning a function in general is pretty useful.
Can you print the error message? I suspect your error is that you want name.capitalize() rather than name.capitalize
Ah - this has already been added!
Related
I am trying to create functions dynamically on the fly or to create functions programmatically in python and am getting stuck at this.
def test(a,b):
print(a)
#Result:
def test(a,b,c):
print(a)
print(b,c)
I am trying it with AST module and failing to understand the AST syntax for function. I understand that a function details can be fetched using functionname.__code__.xxx. But I will be unable to make changes since it is readonly. Here is what I am trying:
I tried getting the AST dump of the above function and it didnt work.
Trying to get the string version of function definition (couldnt find reference)
I have also tried the below but feel that it may be an issue somewhere like when there is a re-assignation which makes it local:
def tests(a,b):
print(a,b)
def mytest(c):
print(a,b,c)
return mytest
def tests(a,b):
print(a,b)
def mytest(c):
print(a,b,c)
a = 10 # this will become local variable
return mytest
I am on python 3.x
Any help or any other easier way?
This may be an OS problem since I did saw on youtube videos where people were demoing how to use decorators in python in a Linux based system.
So I'm trying to play with decorators. In its usual form, you create a function of it first, and then you use the special keywoard "#func_name" in order to pass the next line of arguments into the function. This particular method of utilizing decorator is not working. I've tried in PyDev (Eclipse) and it is just reading as syntax error. I also tried the interactive Python.
Currently running windows OS 7 Python Version 2.78
Here are more specific examples
def c(n):
def d():
return "Hello world",n
return d()
c=c("of Python")
print c
output: ('Hello world', 'of Python')
#c
"of Python"
output: "of Python?"
^
SyntaxError: invalid syntax
Created a working version based on Jon's answer
def c(n):
def d():
return "Hello world" + n()
return d
#c
def decorate_this_func():
return " python"
print decorate_this_func()
then you use the special keywoard "#func_name" in order to pass the
next line of arguments into the function
That's not how decorators work. You can pass arguments to a decorator like this
#c("of python")
def decorate_this_func():
pass
But for that to work you need to tweak your decorator function a bit.
Give this a read https://stackoverflow.com/a/1594484/1843331
It's an excellent explanation of decorators, how they work, how to use arguments with decorators and much more.
Is there a way to format with the new format syntax a string from a function call? for example:
"my request url was {0.get_full_path()}".format(request)
so it calls the function get_full_path function inside the string and not as a parameter in the format function.
EDIT:
Here is another example that will probably show my frustration better, this is what I would like:
"{0.full_name()} {0.full_last_name()} and my nick name is {0.full_nick_name()}".format(user)
this is what I want to avoid:
"{0} and {1} and my nick name is {2}".format(user.full_name(), user.full_last_name(), user.full_nick_name())
Not sure if you can modify the object, but you could modify or wrap the object to make the functions properties. Then they would look like attributes, and you could do it as
class WrapperClass(originalRequest):
#property
def full_name(self):
return super(WrapperClass, self).full_name()
"{0.full_name} {0.full_last_name} and my nick name is {0.full_nick_name}".format(user)
which IS legal.
Python 3.6 adds literal string interpolation, which is written with an f prefix. See PEP 0498 -- Literal String Interpolation.
This allows one to write
>>> x = 'hello'
>>> s = f'{x}'
>>> print(s)
hello
It should be noted that these are not actual strings, but represent code that evaluates to a string each time. In the above example, s will be of type str, with value 'hello'. You can't pass an f-string around, since it will be evaluated to the result str before being used (unlike str.format, but like every other string literal modifier, such as r'hello', b'hello', '''hello'''). (PEP 501 -- General purpose string interpolation (currently deferred) suggests a string literal that will evaluate to an object which can take substitutions later.)
Python does not directly support variable interpolation. This means that it lacks certain functionality (namely, function calling in strings) which other languages support.
So, there isn't really anything to say here other than no, you can't do that. That's just not how Python's formatting syntax works.
The best you have is this:
"my request url was {0}".format(request.get_full_path())
What about this very weird thing?
"my request url was %s and my post was %s"\
% (lambda r: (r.get_full_path(), r.POST))(request)
Explanation:
Classic way of formatting
Lambda function which takes a request and returns a tuple with what you want
Call the lambda inline as arguments for your string.
I still prefer the way you're doing it.
If you want readability you can do this:
path, post = request.get_full_path(), request.POST
"my request url was {} and my post was {}".format(path, post)
So summary of methods would be
(base) [1]~ $ cat r.py
# user is dict:
user = {'full_name': 'dict joe'}
print('{0[full_name]}'.format(user))
# user is obj:
class user:
#property
def full_name(self):
return 'attr joe'
print('{0.full_name}'.format(user()))
# Wrapper for arbitray values - as dict or by attr
class Getter:
def __init__(self, src):
self.src = src
def __getitem__(self, k):
return getattr(self.src, k, 'not found: %s' % k)
__getattr__ = __getitem__
print('{0[foo]} - {0.full_name}'.format(Getter(user())))
(base) [1]~ $ python r.py
dict joe
attr joe
not found: foo - attr joe
I have the following Python code (I'm using Python 2.7.X):
my_csv = '{first},{middle},{last}'
print( my_csv.format( first='John', last='Doe' ) )
I get a KeyError exception because 'middle' is not specified (this is expected). However, I want all of those placeholders to be optional. If those named parameters are not specified, I expect the placeholders to be removed. So the string printed above should be:
John,,Doe
Is there built in functionality to make those placeholders optional, or is some more in depth work required? If the latter, if someone could show me the most simple solution I'd appreciate it!
Here is one option:
from collections import defaultdict
my_csv = '{d[first]},{d[middle]},{d[last]}'
print( my_csv.format( d=defaultdict(str, first='John', last='Doe') ) )
"It does{cond} contain the the thing.".format(cond="" if condition else " not")
Thought I'd add this because it's been a feature since the question was asked, the question still pops up early in google results, and this method is built directly into the python syntax (no imports or custom classes required). It's a simple shortcut conditional statement. They're intuitive to read (when kept simple) and it's often helpful that they short-circuit.
Here's another option that uses the string interpolation operator %:
class DataDict(dict):
def __missing__(self, key):
return ''
my_csv = '%(first)s,%(middle)s,%(last)s'
print my_csv % DataDict(first='John', last='Doe') # John,,Doe
Alternatively, if you prefer using the more modern str.format() method, the following would also work, but is less automatic in the sense that you'll have explicitly define every possible placeholder in advance (although you could modify DataDict.placeholders on-the-fly if desired):
class DataDict(dict):
placeholders = 'first', 'middle', 'last'
default_value = ''
def __init__(self, *args, **kwargs):
self.update(dict.fromkeys(self.placeholders, self.default_value))
dict.__init__(self, *args, **kwargs)
my_csv = '{first},{middle},{last}'
print(my_csv.format(**DataDict(first='John', last='Doe'))) # John,,Doe
I faced the same problem as yours and decided to create a library to solve this problem: pyformatting.
Here is the solution to your problem with pyformatting:
>>> from pyformatting import defaultformatter
>>> default_format = defaultformatter(str)
>>> my_csv = '{first},{middle},{last}'
>>> default_format(my_csv, first='John', last='Doe')
'John,,Doe'
The only problem is pyformatting doesn't support python 2. pyformatting supports python 3.1+
If i see any feedback on the need for 2.7 support i think i will add that support.
Apparently, the following line is not valid Python syntax.
while (!is_int(1)):
How do I fix it?
Note: I don't know Python.
Boolean NOT is written not in Python:
while not is_int(1):
(Assuming you've implemented a function is_int.)
Why define your own function is_int if you have the built-in function isinstance?
while not isinstance(1, int):
The correct syntax is:
while not is_int(1):
....
Where is_int can be implemented as:
def is_int(arg):
return isinstance(arg, int)