吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 947|回复: 16
收起左侧

[已解决] 关于python的转义语法

[复制链接]
RGstar 发表于 2020-8-18 22:18
本帖最后由 RGstar 于 2020-8-19 09:07 编辑

小弟刚学习python3.0,跟的小甲鱼的书。遇到了一个疑问:
以下两种情况,请问为啥字符串不会转义,print的时候会执行转义呢?
请问是什么语法导致的吗?
[Asm] 纯文本查看 复制代码
>>> 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")  就可以解决~我也是今晚学习的时候发现的

这个我也知道 只是纠结为啥会有两种情况
 楼主| RGstar 发表于 2020-8-18 23:26
似水流年2015 发表于 2020-8-18 22:43
这个就不要纠结了吧,只要记住可以通过print(r"\n")  来去除转义  或者  print("\\n")  .深层原因我也不懂, ...

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

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

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
RGstar + 1 + 1 谢谢@Thanks!

查看全部评分

爱飞的猫 发表于 2020-8-18 23:44
>>> string
'C:\now'

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

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
RGstar + 1 + 1 谢谢@Thanks!

查看全部评分

百尺书生 发表于 2020-8-18 23:55
\是转义字符,通过转义字符,可以在字符串中使用一些特殊的内容,\n表示换行。
飞畅 发表于 2020-8-19 00:18
本帖最后由 飞畅 于 2020-8-19 01:54 编辑

[Python] 纯文本查看 复制代码
>>> 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/
---------------------分割线------------------
源码分析:[https://www.python.org/ftp/python/3.6.4/Python-3.6.4.tgz]
在[Python/bltinmodule.c]里,看到了print的实现
[C] 纯文本查看 复制代码
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的实现
[Objects/fileobject.c]

[C] 纯文本查看 复制代码
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)
Snipaste_2020-08-19_01-29-38.png

PyObject_Repr和PyObjet_Str的实现
[Objects/object.c]
[C] 纯文本查看 复制代码
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__

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
RGstar + 1 + 1 谢谢@Thanks!

查看全部评分

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吾爱币 +1 热心值 +1 收起 理由
RGstar + 1 + 1 谢谢@Thanks!

查看全部评分

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-26 13:45

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表