【问题标题】:What does the print function actually do other than displaying it?除了显示它之外,打印功能实际上做了什么?
【发布时间】:2019-07-21 04:05:18
【问题描述】:

打印功能做了超出预期的事情,并且这种行为因语言而异。请查看给定的代码。

Python 3 代码:

n=print("Interesting")
print(n)

输出:

Interesting
None

C 代码:

#include<stdio.h>
int main(){
    int n = printf("Interesting");
    printf("\n%d",n);

}

输出:

Interesting
11

我预计输出是某种错误,但两种语言的处理方式不同。请解释为什么会发生这种情况,打印功能除了显示之外还能做其他事情吗?

【问题讨论】:

  • 在 Python 中,每个函数都会返回一些东西,至少是 None
  • 您可以查看参考资料以了解每个函数在做什么:printprintf。也不清楚为什么你会期望来自两种不同语言的这两个非常不同的函数返回相同的东西。
  • 比较两种不同编程语言名称相似的两个函数是没有意义的。
  • 在 C 中,printf() can change a variable:int n = -42; printf("foo%nbar\n", &amp;n); printf("new n is %d\n", n);
  • 在英文中,bald的意思是没有头发。在德语中,bald 的意思是“很快”。为什么会有差异?

标签: python c python-3.x


【解决方案1】:

printprintf 是可以有返回值的函数。在 Python 中,print 只返回 None

在 C 中,printf 的签名是int printf( const char* format, ... );。它返回一个等于输出字符数的整数。负返回值表示发生了错误。

【讨论】:

    【解决方案2】:

    每种语言的 print 功能都有不同的作用。

    Python 3.0 及更高版本 中,它是一个完全充实的内置函数。它的角色比 C 等低级语言的常见角色要多得多。见https://docs.python.org/3/whatsnew/3.0.html

    在 Python 中,print() 内置函数有 3 个主要用途。

    1) 灵活的调试工具:

    def myfunc(var):
        ''' This function returns the square of a number. '''
        varsquare = var * var  
        print("function steps:", var, varsquare)
        return varsquare
    result = myfunc(5):
    print("input=", 5, "output=", result)
    
    ### sample outputs:
    > function steps: 5 25
    > input= 5 output= 25
    

    2) 灵活的python模块文档字符串探索工具: https://www.pythonforbeginners.com/basics/python-docstrings

    # Three different ways to "print" an object's documentation string.
    
    # Print a local function's docstring.
    print myfunc.__doc__
    # output: 
    > This function returns the square of a number.
    
    # Print the docstrings of an imported module and its class.
    import mymodule   
    print mymodule.__doc__
    print mymodule.MyClass.__doc__
    
    ##### Example mymodule.py file.  #########
    """
    Assuming this is file mymodule.py, then this string, being the
    first statement in the file, will become the "mymodule" module's
    docstring when the file is imported.
    """
    
    class MyClass(object):
        """The class's docstring"""
    
    def my_method(self):
        """The method's docstring"""
    
    def my_function():
        """The function's docstring"""
    

    3) 开发过程中,对象检查角色:

    import numpy as np
    print(np)
    
    # output:
    > <module 'numpy' from 'C:\\python\\conda3\\envs\\pyfin\\lib\\site- 
    > packages\\numpy\\__init__.py'>
    
    var2 = np.arange(10).reshape(2, 5)
    print(var2)
    # output:
    > [[0 1 2 3 4]
    > [5 6 7 8 9]]
    

    可能还有其他用途,但我想到了这 3 个。

    【讨论】:

      【解决方案3】:

      Python 中的内置打印函数是用 C 实现的,但是,与 C 版本不同的是,它不会返回它在输出对象上写入的字符数。要检查它返回的内容,请查看源代码。来自 Python 的源代码Git 仓库:

      builtin_print(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
      {
          static const char * const _keywords[] = {"sep", "end", "file", "flush", 0};
          static struct _PyArg_Parser _parser = {"|OOOO:print", _keywords, 0};
          PyObject *sep = NULL, *end = NULL, *file = NULL, *flush = NULL;
          int i, err;
      
          if (kwnames != NULL &&
                  !_PyArg_ParseStackAndKeywords(args + nargs, 0, kwnames, &_parser,
                                                &sep, &end, &file, &flush)) {
              return NULL;
          }
      
          if (file == NULL || file == Py_None) {
              file = _PySys_GetObjectId(&PyId_stdout);
              if (file == NULL) {
                  PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
                  return NULL;
              }
      
              /* sys.stdout may be None when FILE* stdout isn't connected */
              if (file == Py_None)
                  Py_RETURN_NONE;
          }
      
          if (sep == Py_None) {
              sep = NULL;
          }
          else if (sep && !PyUnicode_Check(sep)) {
              PyErr_Format(PyExc_TypeError,
                           "sep must be None or a string, not %.200s",
                           sep->ob_type->tp_name);
              return NULL;
          }
          if (end == Py_None) {
              end = NULL;
          }
          else if (end && !PyUnicode_Check(end)) {
              PyErr_Format(PyExc_TypeError,
                           "end must be None or a string, not %.200s",
                           end->ob_type->tp_name);
              return NULL;
          }
      
          for (i = 0; i < nargs; 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(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;
      
          if (flush != NULL) {
              PyObject *tmp;
              int do_flush = PyObject_IsTrue(flush);
              if (do_flush == -1)
                  return NULL;
              else if (do_flush) {
                  tmp = _PyObject_CallMethodIdNoArgs(file, &PyId_flush);
                  if (tmp == NULL)
                      return NULL;
                  else
                      Py_DECREF(tmp);
              }
          }
      
          Py_RETURN_NONE;
      }
      

      在上面的代码中,您可以看到该函数使用属性处理程序 Py_RETURN_NONE 返回 None,这是一个从 C 函数返回 None 的属性句柄。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-02
        • 2020-11-21
        • 2015-02-26
        • 2017-06-29
        • 2013-06-13
        • 2021-10-25
        • 2011-08-12
        • 1970-01-01
        相关资源
        最近更新 更多