4

I'm basically trying to make a quine in python and first tried with f-strings, but I quickly realized that I first have to define the variables I want to format inside the string. I then learned about string templates and figured that would be the way to go. I am however not that experienced with it and could need some help. Any suggestions?

Here's the actual code:

from string import Template
s="from string import Template\ns=$s\nt=Template($s).substitute(s=$s)\nprint($s)"
t=Template(s).substitute(s=s)
print(s)

It gives me somewhat of the right result. The only problem is that it's not replacing the $s with the actual string. I've might just have misunderstood the whole concept with quines and the method of doing them but I feel this should work.

Output:

from string import Template
s=$s
t=Template($s).substitute(s=$s)
print($s)
Goby
  • 57
  • 4

2 Answers2

4

I'm not sure how this would be done using string.Template, but you could use str.format as a straightforward replacement to f-strings that suits this task, as it allows you to delay the interpolation of the s variable:

s='s={0!r}\nprint(s.format(s))'
print(s.format(s))

Output:

s='s={0!r}\nprint(s.format(s))'
print(s.format(s))

The !r is used to get the repr of s, which wraps it in quotes, and escapes the newlines.

Will Da Silva
  • 6,386
  • 2
  • 27
  • 52
  • The key here is the `!r` modifier/directive, which uses `repr` instead of `str`. This is how you can recover the quotation marks, because th default `repr` implementation for strings is to return the string in quoted form, like what you would type in Python source code. I am not sure if there is a way to do this with `string.Template`. – shadowtalker Sep 25 '21 at 20:39
  • What is the ```0``` for in ```{0!r}```? – Goby Sep 25 '21 at 21:04
  • The index of the element provided to `str.format`, i.e. the first element we passed into `str.format`, which is `s`. – Will Da Silva Sep 25 '21 at 21:05
0

I've taken the advice from @Will Da Silva and included the repr() function in my method of doing it as seen below:

from string import Template
s='from string import Template\ns=$s\nt=Template(s)\nprint(t.substitute(s=repr(s)))'
t=Template(s)
print(t.substitute(s=repr(s)))

I think the problem was that it interpreted the string as code and in turn made a new line at every \n. But now when it keeps the quotation marks it just sees it as a string.

Goby
  • 57
  • 4