关于python的转义语法
本帖最后由 RGstar 于 2020-8-19 09:07 编辑小弟刚学习python3.0,跟的小甲鱼的书。遇到了一个疑问:
以下两种情况,请问为啥字符串不会转义,print的时候会执行转义呢?
请问是什么语法导致的吗?
>>> string='C:\now'
>>> string
'C:\now'
>>> print(string)
C:
ow string=(r"C:\now")就可以解决~我也是今晚学习的时候发现的 这个就不要纠结了吧,只要记住可以通过print(r"\n")来去除转义或者print("\\n").深层原因我也不懂,但简单理解为 当你用变量方式输出时,是查看变量内的值,所以没转义,当用print时,是运行输出,所以就转义了. 初学还是建议不纠结这些小问题,先记住,后面学起来了,再对这些小细节 一个个深究,会觉得收获无穷,豁然开朗 zhang1497 发表于 2020-8-18 22:33
string=(r"C:\now")就可以解决~我也是今晚学习的时候发现的
这个我也知道 只是纠结为啥会有两种情况{:301_977:} 似水流年2015 发表于 2020-8-18 22:43
这个就不要纠结了吧,只要记住可以通过print(r"\n")来去除转义或者print("\\n").深层原因我也不懂, ...
的确有时候太纠结会拖慢效率{:301_995:}有点钻牛角尖似的 RGstar 发表于 2020-8-18 23:26
的确有时候太纠结会拖慢效率有点钻牛角尖似的
我也从新手走过来,入门时各种坑,现在还在菜鸟阶段徘徊,终于懂了:理解不了时,先放一边,继续往下学习,命令不要强迫自己记住 ,也不要因为命令或流程没达到完全默记而沮丧影响学习信心。。。。你只要达到能一边百度,一边写出代码并成功运行得出你要的结果就行。。。。。。。毕竟正式程序员也是一个屏幕百度,一个屏幕写代码的。 不要强迫自己记住所有命令,太难了。 >>> string
'C:\now'
执行这个的时候在交互式控制台弹出来的是可以直接复制执行的。 \是转义字符,通过转义字符,可以在字符串中使用一些特殊的内容,\n表示换行。 本帖最后由 飞畅 于 2020-8-19 01:54 编辑
>>> a="C:\now"
>>> a.__repr__()
"'C:\\now'"
>>> a.__str__()
'C:\now'
>>> print(a.__repr__())
'C:\now'
>>> print(a.__str__())
C:
ow
个人理解:直接在控制台输入变量展示的时候,是通过字符串的内置函数__repr__()输出字符串的
print()输出展示的时候,是通过内置函数__str__()输出字符串的
前者主要用于调试,后者主要用于输出交互
更准确的还得看源码
https://www.python.org/downloads/source/
---------------------分割线------------------
源码分析:
在里,看到了print的实现
static PyObject *
builtin_print(PyObject *self, PyObject *args, PyObject *kwds)
{
...
for (i = 0; i < PyTuple_Size(args); i++) {
if (i > 0) {
if (sep == NULL)
err = PyFile_WriteString(" ", file);
else
err = PyFile_WriteObject(sep, file,
Py_PRINT_RAW);
if (err)
return NULL;
}
err = PyFile_WriteObject(PyTuple_GetItem(args, i), file,
Py_PRINT_RAW);
if (err)
return NULL;
}
if (end == NULL)
err = PyFile_WriteString("\n", file);
else
err = PyFile_WriteObject(end, file, Py_PRINT_RAW);
if (err)
return NULL;
...
Py_RETURN_NONE;
}
也就是对print传来的参数元组,一个个的调用PyFile_WriteObject往文件里写,默认的是stdout
PyFile_WriteObject的实现
int
PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
{
...
if (flags & Py_PRINT_RAW) {
value = PyObject_Str(v);
}
else
value = PyObject_Repr(v);
if (value == NULL) {
Py_DECREF(writer);
return -1;
}
result = _PyObject_CallArg1(writer, value);
...
return 0;
}
可以看到如果是从builtin_print函数过来的话,flag参数就是Py_PRINT_RAW,两者位与为真,于是调用PyObject_Repr(v)获得要输出的字符串
否则,调用的就是PyObject_Str(v)
PyObject_Repr和PyObjet_Str的实现
PyObject *
PyObject_Repr(PyObject *v)
{
...
res = (*v->ob_type->tp_repr)(v);
...
return res;
}
PyObject *
PyObject_Str(PyObject *v)
{
...
res = (*Py_TYPE(v)->tp_str)(v);
...
return res;
}
PyObject_Repr和PyObject_Str内部会调__repr__和__str__ 10楼正解,因为print调用的是字符串类中的运算符__str__,里面把转义字符都单独设定好输出方式了。
但是因为你看的内容还没到10楼说的那里,即运算符重载,所以你可能难以理解,但等你学完OOP之后就可以理解为何了,
为了让你能够在现阶段暂时性理解大概的原因,你可以写一段如下的代码:
class Test:
def __init__(self,str):
self.str = str
def __str__(self):
return "10楼说的对"
a = Test("C:\now")
print(a)
print(a.str)
a和你的string本质上都是类的实例,而你看打印a会出现什么,你就明白,其实print本身只是做运算符__str__里规定的事情罢了,也就是说,如果你愿意,也可以再设定一些额外的“转义字符”到你所定义的“字符串”里也毫无问题
页:
[1]
2