RGstar 发表于 2020-8-18 22:18

关于python的转义语法

本帖最后由 RGstar 于 2020-8-19 09:07 编辑

小弟刚学习python3.0,跟的小甲鱼的书。遇到了一个疑问:
以下两种情况,请问为啥字符串不会转义,print的时候会执行转义呢?
请问是什么语法导致的吗?
>>> string='C:\now'
>>> string
'C:\now'
>>> print(string)
C:
ow

zhang1497 发表于 2020-8-18 22:33

string=(r"C:\now")就可以解决~我也是今晚学习的时候发现的

似水流年2015 发表于 2020-8-18 22:43

这个就不要纠结了吧,只要记住可以通过print(r"\n")来去除转义或者print("\\n").深层原因我也不懂,但简单理解为 当你用变量方式输出时,是查看变量内的值,所以没转义,当用print时,是运行输出,所以就转义了. 初学还是建议不纠结这些小问题,先记住,后面学起来了,再对这些小细节 一个个深究,会觉得收获无穷,豁然开朗

RGstar 发表于 2020-8-18 23:25

zhang1497 发表于 2020-8-18 22:33
string=(r"C:\now")就可以解决~我也是今晚学习的时候发现的

这个我也知道 只是纠结为啥会有两种情况{:301_977:}

RGstar 发表于 2020-8-18 23:26

似水流年2015 发表于 2020-8-18 22:43
这个就不要纠结了吧,只要记住可以通过print(r"\n")来去除转义或者print("\\n").深层原因我也不懂, ...

的确有时候太纠结会拖慢效率{:301_995:}有点钻牛角尖似的

似水流年2015 发表于 2020-8-18 23:32

RGstar 发表于 2020-8-18 23:26
的确有时候太纠结会拖慢效率有点钻牛角尖似的

我也从新手走过来,入门时各种坑,现在还在菜鸟阶段徘徊,终于懂了:理解不了时,先放一边,继续往下学习,命令不要强迫自己记住 ,也不要因为命令或流程没达到完全默记而沮丧影响学习信心。。。。你只要达到能一边百度,一边写出代码并成功运行得出你要的结果就行。。。。。。。毕竟正式程序员也是一个屏幕百度,一个屏幕写代码的。   不要强迫自己记住所有命令,太难了。

爱飞的猫 发表于 2020-8-18 23:44

>>> string
'C:\now'

执行这个的时候在交互式控制台弹出来的是可以直接复制执行的。

百尺书生 发表于 2020-8-18 23:55

\是转义字符,通过转义字符,可以在字符串中使用一些特殊的内容,\n表示换行。

飞畅 发表于 2020-8-19 00:18

本帖最后由 飞畅 于 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__

ukyodz 发表于 2020-8-19 01:04

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
查看完整版本: 关于python的转义语法