2.从print到自省
print是一个函数
为什么print是一个函数呢?可以在交互式解释器下
输入:
>>> type(print)
输出:
<class 'builtin_function_or_method'>
这句话的意思是说,print的类型是一个内建的函数或方法,class只是起指示作用,与类定义时的class作用不同,而'builtin_function_or_method'是一段描述性文本,不需要在意其中的下划线,我相信它仅仅是python想输出的一段文本而已,有无这下划线并不妨碍说明print是一个函数。
如何使用print函数
可以在交互式解释器下
输入:
>>> print.__doc__
输出:
"print(value, ..., sep=' ', end='\\n', file=sys.stdout, flush=False)\n\nPrints the
values to a stream, or to sys.stdout by default.\nOptional keyword arguments:
\nfile: a file-like object (stream); defaults to the current sys.stdout.\nsep:
string inserted between values, default a space.\nend: string appended after
the last value, default a newline.\nflush: whether to forcibly flush the stream."
从这段文档来看,要使用print函数,就应该如同文档所给出的那种形式:print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False),可以看到其中非常可能变化的参数是"value,...,",而不需要变化的参数是sep和它后面的参数(默认参数)。如果想要改变打印的方式,就需要改变这些默认参数。如果不提供参数,那么就打印出一个空行代码如下:
1 .value, ...,
>>> print('a') # 打印单个字符串,其他参数默认
a
>>> print('a', 'b', 'c') # 打印多个字符串
a b c
2 .sep
>>> print('a', 'b', 'c', sep=',') # 用逗号将结果隔开
a,b,c
3 .end
新建.py文件,保存运行
输入:
print('hello,') # 打印结束默认换行
print('world!')
输出:
hello,
world!
新建.py文件,保存运行
输入:
print('hello,end="***"') # 打印结束不换行,而是加三颗星*
print('world!')
输出:
hell,***world!
4 .file
输入
with open(r'D:\python36\print_file.txt', 'w') as f:
print('a', 'b', 'c', file=f)
如果不改变file参数默认值,print直接是显示在解释器上,因为sys.stdout指向控制台,所以sys.stdout是print默认的输出格式,如果改变了file参数,如上面代码那样这时屏幕上就不会再显示a b c,而是写在刚刚新建的(如果原先没有这个文件就会新建这个文件)文件中。还是看代码直观。
>>> print("hello, world!")
hello, world!
>>> import sys
>>> sys.stdout.write("hello, world!")
hello, world!13
>>> sys.stdout.write("hello, world!\n")
hello, world!
14
>>> help(sys.stdout.write)
Help on method write in module idlelib.run:
write(s) method of idlelib.run.PseudoOutputFile instance
Write string to stream.
Returns the number of characters written (which is always equal to
the length of the string).
>>>
不翻译了,对于sys.stdout引用python教程的一段话解释:“变量sys.stdin、sys.stdout和sys.stderr是类似于文件的流对象,表示标准的UNIX概念:标准输入、标准输出和标准错误。简单地说,Python从sys.stdin获取输入(例如,用于input中),并将输出打印到sys.stdout。你提供给print的文本出现在sys.stdout中,向input提供的提示信息也出现在这里。写入到sys.stdout的数据通常出现在屏幕上,但可使用管道将其重定向到另一个程序的标准输入。”--python3基础教程。
5 .flush=False
从flush参数的值可以看出,flush=False/True,表示是否立刻将输出语句输入到参数file指向的对象中(默认是sys.stdout)
输入
>>> f=open(r'print_flush.txt', 'w')
>>> print('a', 'b', 'c', file=f)
# 此时,txt文件没有任何东西写入,print的内容存在内存中,直到文件关闭,输出到txt中输入
>>> f=open(r'print_flush.txt', 'w')
>>> print('a', 'b', 'c', file=f, flush=True) # 此时,txt文件已经写入a b c
先不管为何先存到内存中,以后再写。更详细了解可以参考python中文文档
6 .不传递参数
不传递参数给print()函数,它将打印出一个空行。
>>> print()
>>>
7 .print函数返回了什么?
既然是一个函数,无论如何,返回值是最重要的,最终还是要看结果嘛,默认情况下,print函数将(value, ...)打印到流或sys.stdout,但它的返回值是None,这将在文章快结束的时候印证这一点。
print的属性
python中要查看一个对象的属性,可以用dir()函数,
输入:
dir(print)
输出:
['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '
__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__',
'__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__',
'__self__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__text_signature__']
dir函数返回传递给它的任何对象的属性名称经过排序的列表,这里的属性很丰富,注意到这些属性都是以双下划线开始和结束,在python中这有特殊的意义它代表一些特殊的方法,方法也是属性,这里主要说下__str__和__repr__
1 .__str__
既然__str__是print的一个属性,那么我们就可以通过他的"对象"+."属性"的形式去查看这个属性到底是什么东西__doc__属性查看这个对象的注释,
输入:
>>> print.__str__
输出:
<method-wrapper '__str__' of builtin_function_or_method object at 0x005A0120>
顺手牵羊输入>>>print.__str__,结果也是如同上面那样,这说明了__str__和__repr__都是print的一个封装方法,id相同意味指向相同的内存地址,相同的对象!
接着输入:
>>> print.__str__.__doc__
输出:
'Return str(self).'
str()是什么?是python的一个内置函数!
继续输入:
>>> type(str())
<class 'str'> #输出
>>> type(str)
<class 'type'> # 输出
class str(object='')
class str(object=b'', encoding='utf-8', errors='strict')
那么str()返回的是什么?——返回object的字符串版本。如下:
输入:
>>> str('a')
'a' #输出
>>> str(1)
'1'
2.__repr__
同理所得:
>>> print.__repr__
<method-wrapper '__repr__' of builtin_function_or_method object at 0x005A0120>
>>> print.__repr__.__doc__
'Return repr(self).'
>>> repr('a')
"'a'"
>>> repr(1)
'1'
repr()返回了什么?repr(object)返回一个包含对象可打印表示的字符串。对于许多类型,此函数尝试返回一个字符串,该字符串在传递给eval()时会产生一个具有相同值的对象,否则该表示是一个用尖括号括起来的字符串,其中包含名称该对象的类型以及经常包括该对象的名称和地址的附加信息。一个类可以通过定义一个__repr__()方法来控制该函数为其实例返回的内容。
引号去了哪儿?
>>> print('hello, world!')
hello, world!
无论是在交互式解释器运行,还是在程序中运行,print('hello, world!')都没有出现引号,那么引号去了哪里?
这只是print函数显示结果打印到屏幕的形式,当它显示时引号就被去掉,仅此而已。其实引号只是起到一种标识的作用,并不是字符串的一部分,可以很容易验证,比如len('abc')的结果是3而不是5。但不能说abc是一个字符串,abc脱离引号''没有意义,所以print函数返回的值都是None。顺便说一句,print(repr('a')),为什么就显示出引号(结果为'a')?,这不矛盾啊,因为repr('a')返回的结果是"'a'",而print函数在打印的时候吧外面的双引号去掉,也是仅此而已。不过,repr函数却使字符串'a'通过repr函数变成了"'a'",即两个单引号也成为了字符串的一部分,字符串长度由1变成3,在“再谈print()、str()、repr()”一节有代码说明。
>>> len('abc')
3
为何引号又出现了?
>>> a='b'
>>> a
'b'
>>> print(a)
b
print函数直接将a打印出来,它是不包含引号的,据说print语句使用str()函数显示对象,交互解释器调用repr()函数来显示对象,但我无法通过python自省等方式得知。这样?print(repr(object))...。
再谈print、str()、repr()
前面的比较仍然是不够短兵相接,我想更近距离的进行比较或许能更加直观,一次性的在交互式解释器横向比较怎么样?
输入:
>>> b='a'
>>> type(b)
<class 'str'>
>>> len(b)
1
>>> type(print())
<class 'NoneType'>
>>> type(print(b))
a
<class 'NoneType'>
>>> print(b)==None
a
True
>>> id(type(print(b)))
a
1610549680
>>> id(a)
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
id(a)
NameError: name 'a' is not defined
>>> len(print(b))
a
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
len(print(b))
TypeError: object of type 'NoneType' has no len()
>>> str(b)
'a'
>>> type(str(b))
<class 'str'>
>>> len(str(b))
1
>>> repr(b)
"'a'"
>>> type(repr(b))
<class 'str'>
>>> len(repr(b))
3
结合前面的说明,可以更清楚的看到,当给repr传一个字符,那么这个函数返回的是一个带引号的字符,长度也增加了2,这,就是它和str()的区别所在;而type(print(b))的结果为NoneType,则说明print(b)的值是None,但print(b)是占据内存的(值是None), 而a不占有内存,a既不被引用也不被定义而且也不等于None,那么这里的a是什么?由于我们看到的a没有了两个单引号,变得没有意义,当将a交给解释器的时候,解释器也不知道他是什么,所以引发了,这大概是从解释器的角度和从用户的角度看所呈现的“奇观”。这段程序在交互式下和作为脚本运行结果都一样
最后的安利
最后的最后,能安利一波最好了!没错,我就是要安利python的自省机制,这里给出安利的链接python自省指南,为啥不在开头给出?因为无论如何,至少到最后能给大家安排上车,就算读到最后还是不知道笔者在扯啥!呃,为啥三个大于号有的颜色不一致?下面附上相关的文档引用
附录相关文档
repr(object)
Return a string containing a printable representation of an object. For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to eval(), otherwise the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object. A class can control what this function returns for its instances by defining a repr() method.
class str(object='')
class str(object=b'', encoding='utf-8', errors='strict')
Return a string version of object. If object is not provided, returns the empty string. Otherwise, the behavior of str() depends on whether encoding or errors is given, as follows.
object.__repr__(self)
由repr()内建函数和调用以计算一个对象的“正式”的字符串表示。如果可能的话,这应该看起来像一个有效的Python表达式,可用于重新创建具有相同值的对象(给定适当的环境)。如果不可能,应该返回<...some useful description...>形式的字符串。返回值必须是一个字符串对象。如果一个类定义了__repr__()但没有定义__str__(),那么在请求该类的实例的“非正式”的字符串表示时也将调用__repr__()。
object.__str__(self)
由str(object)、内建函数format()和print()语句调用,以计算一个对象的“非正式的”或可打印的字符串表示。返回值必须是一个字符串对象。
与object.__repr__()不同的是,str()不需要返回一个合法的Python表达式:可以使用更合适或者精确的表示。
内建类型object默认的实现是调用object.__repr__()。
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
Print objects to the text stream file, separated by sep and followed by end. sep, end, file and flush, if present, must be given as keyword arguments.
All non-keyword arguments are converted to strings like str() does and written to the stream, separated by sep and followed by end. Both sep and end must be strings; they can also be None, which means to use the default values. If no objects are given, print() will just write end.
The file argument must be an object with a write(string) method; if it is not present or None, sys.stdout will be used. Since printed arguments are converted to text strings, print() cannot be used with binary mode file objects. For these, use file.write(...) instead.
Whether output is buffered is usually determined by file, but if the flush keyword argument is true, the stream is forcibly flushed.
2.从print到自省的更多相关文章
- Python自省(反射)指南
在笔者,也就是我的概念里,自省和反射是一回事,当然其实我并不十分确定一定以及肯定,所以如果这确实是两个不同的概念的话,还请多多指教 :) 转载请注明作者.出处并附上原文链接,多谢!update 201 ...
- python 学习笔记 9 -- Python强大的自省简析
1. 什么是自省? 自省就是自我评价.自我反省.自我批评.自我调控和自我教育,是孔子提出的一种自我道德修养的方法.他说:“见贤思齐焉,见不贤而内自省也.”(<论语·里仁>)当然,我们今天不 ...
- Python强大的自省简析
1. 什么是自省? 自省就是自我评价.自我反省.自我批评.自我调控和自我教育,是孔子提出的一种自我道德修养的方法.他说:"见贤思齐焉,见不贤而内自省也."(<论语·里仁> ...
- Python自省
自省就是通过一定机制查询到对象的内部结构,也就是运行时获取对象内部的属性以及类型,在Python中dir(),type(), hasattr(), isinstance()都是很好的自省例子 #!/u ...
- day25 Python四个可以实现自省的函数,反射
python面向对象中的反射:通过字符串的形式操作对象相关的属性.python中的一切事物都是对象(都可以使用反射) 四个可以实现自省的函数 下列方法适用于类和对象(一切皆对象,类本身也是一个对象) ...
- [py]python自省工具
参考 在日常生活中,自省(introspection)是一种自我检查行为.自省是指对某人自身思想.情绪.动机和行为的检查.伟大的哲学家苏格拉底将生命中的大部分时间用于自我检查,并鼓励他的雅典朋友们也这 ...
- python的自省函数, 快速找出BUG的良器
python内置的好多自省函数, 合理使用可快速查找相关提示, 快速找到问题点, 以下开始具体说明 1. dir() 列出对象的所有属性和方法 如: dir(list) 可以列出列表的所有属性 ...
- Python自省(反射)指南(转)
原文:http://www.cnblogs.com/huxi/archive/2011/01/02/1924317.html 在笔者看来,自省和反射是一回事,当然其实我并不十分确定一定以及肯定,所以如 ...
- Python自省 type(),dir(),getattr(),hasattr(),isinstance().
Python自省 这个也是python彪悍的特性. 自省就是面向对象的语言所写的程序在运行时,所能知道对象的类型.简单一句就是运行时能够获得对象的类型.比如type(),dir(),getattr() ...
随机推荐
- mybatis3 step by step 快速上手
作者:Panda Fang 出处:http://www.cnblogs.com/lonkiss/p/6895617.html 原创文章,转载请注明作者和出处,未经允许不可用于商业营利活动 官方网站 h ...
- web.xml中不同版本的servlet头以及版本控制
参考文章: http://www.cnblogs.com/beijingstruggle/p/5461146.html http://blog.csdn.net/z69183787/article/d ...
- matlab矩阵
矩阵的转置用',比如: a = [1,2,3]; b = a'; %b 转置成一个列向量,可以用于矩阵 linspace是Matlab中的一个指令,用于产生指定范围内的指定数量点数,相邻数据跨度相同, ...
- js常用函数汇总(不定期更新)
1.图片按比例压缩 function setImgSize(){ var outbox_w=imgbox.width(), outbox_h=imgbox.height(); imgbox.find( ...
- 什么是Load Average?
运维工程师在日常运维中经常使用w.top.uptime等命令来查看系统当前运行的负载情况.那么作为运维工程师是如何通过以上命令来判断系统当前负载是否已经达到极限了呢?为此笔者总结了一下如何通过load ...
- 基于Qt的相似QQ好友列表抽屉效果的实现
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/shuideyidi/article/details/30619167 前段时间在忙毕业设计, ...
- gluon实现softmax分类FashionMNIST
from mxnet import gluon,init from mxnet.gluon import loss as gloss,nn from mxnet.gluon import data a ...
- ACM-ICPC(10 / 9)
ACM-ICPC(10.9) 树形DP 树形DP考点很多,状态转移有时会很复杂,但是也有规律可寻,最重要的是抓住父子关系之间的状态转移. 树的最大独立集:尽量选择多的点,使得任何两个结点均不相邻. ...
- js数组、字符串常用方法
数组方面 push:向数组尾部增加内容,返回的是新数组的长度. var arr = [1,2,3]; console.log(arr); var b = arr.push(4); console.lo ...
- 【luogu P2341 [HAOI2006]受欢迎的牛】 题解
题解报告:https://www.luogu.org/problemnew/show/P2341 我们把图中的强连通分量缩点,然后只有出度为0的牛是受欢迎的,这样如果出度为0的牛只有一个,说明受所有牛 ...