【问题标题】:What are the important language features (idioms) of Python to learn early on [duplicate]早期需要学习的 Python 的重要语言特性(习语)有哪些 [重复]
【发布时间】:2010-10-08 17:03:08
【问题描述】:

我很想知道 StackOverflow 社区认为 Python 的重要语言特性(习语)是什么。将程序员定义为 Pythonic 的功能。

Python (pythonic) 成语 - “代码表达式”是 Python 语言的自然或特征。

另外,所有 Python 程序员都应该尽早学习哪些习语?

提前致谢

相关:

【问题讨论】:

  • 我对以下行感到困惑:“Python (pythonic) idiom - “代码表达式”是 Python 语言的自然或特征” 这是“Idiom”还是“Pythonic”的定义?为什么会在这里?这是什么意思?
  • 是的,我今天的票数不多了。 :)
  • 我刚刚修改了这个问题,这是否有助于使这个问题成为一个独特的问题,“早期”是我询问的核心部分

标签: python idioms


【解决方案1】:

我认为在线教程和书籍只谈论做事,而不是用最好的方式做事。除了 python 语法,我认为在某些情况下速度很重要。

Python 提供了一种对函数进行基准测试的方法,实际上是两个!!

一种方法是使用profile 模块,如下所示:

import profile

def foo(x, y, z):
    return x**y % z # Just an example.

profile.run('foo(5, 6, 3)')

另一种方法是使用timeit 模块,如下所示:

import timeit

def foo(x, y, z):
    return x**y % z # Can also be 'pow(x, y, z)' which is way faster.

timeit.timeit('foo(5, 6, 3)', 'from __main__ import *', number = 100) 
# timeit.timeit(testcode, setupcode, number = number_of_iterations)

【讨论】:

    【解决方案2】:

    就我个人而言,我真的很喜欢使用 缩进 来定义代码块的 Python 语法,而不是使用“BEGIN”和“END”这两个词(就像在 Microsoft 的 Basic 和 Visual Basic 中一样 - 我不喜欢这些)或使用左大括号和右大括号(如在 C、C++、Java、Perl 中 - 我喜欢这些)。

    这真的让我感到惊讶,因为尽管缩进对我来说一直很重要,但我并没有对此产生太大的“噪音”——我接受了它,它被认为是一种能够阅读其他人的技能,“意大利面条”代码。此外,我从未听过其他程序员建议将缩进作为语言的一部分。直到 Python!我只希望我首先意识到这个想法。

    对我来说,就好像 Python 的语法迫使你编写好的、可读的代码。

    好的,我会离开我的肥皂盒。 ;-)

    【讨论】:

      【解决方案3】:

      使用字符串替换:

      name = "Joe"
      age = 12
      print "My name is %s, I am %s" % (name, age)
      

      当我不使用python编程时,我最怀念的是那种简单的使用。

      【讨论】:

        【解决方案4】:

        这里有一个可以提供帮助的。有什么区别:

        [ foo(x) for x in range(0, 5) ][0]
        

        ( foo(x) for x in range(0, 5) ).next()
        

        回答: 在第二个示例中, foo 仅被调用一次。如果 foo 有副作用,或者用于构造列表的可迭代对象很大,这可能很重要。

        【讨论】:

        • 如果foo() 有副作用,我认为您不应该像这样使用它,但重要的是要注意列表推导式创建一个列表,而生成器表达式在迭代时飞行(只能迭代一次,但几乎不使用内存)。
        【解决方案5】:

        另一件你不能及早开始的事情可能是测试。在这里,尤其是 doctests 是通过同时解释代码来测试代码的好方法。

        doctests 是一个简单的文本文件,包含一个交互式解释器会话和如下文本:

        Let's instantiate our class::
        
        >>> a=Something(text="yes")
        >>> a.text
        yes
        
        Now call this method and check the results::
        
        >>> a.canify()
        >>> a.text
        yes, I can
        

        如果例如a.text 返回不同的东西,测试将失败。

        doctests 可以在 docstrings 或独立的文本文件中,并使用doctests module 执行。当然也可以使用更知名的单元测试。

        【讨论】:

          【解决方案6】:

          Python 中的一个重要习惯用法是文档字符串。

          每个对象都有一个 __doc__ 属性,可用于获取有关该对象的帮助。您可以像这样在模块、类、方法和函数上设置 __doc__ 属性:

          # this is m.py
          """ module docstring """
          
          class c:
              """class docstring"""
              def m(self):
                  """method docstring"""
                  pass
          
          def f(a):
              """function f docstring"""
              return
          

          现在,当您键入 help(m)help(m.f) 等时,它将打印文档字符串作为帮助消息。

          因为它只是普通对象自省的一部分,所以它可以被 epydoc 等文档生成系统使用,或者被 unittest 用于测试目的。

          它还可以用于更非传统(即非惯用)的用途,例如 Dparser 中的语法。

          让我更感兴趣的是,即使 doc 是大多数对象的只读属性,您也可以像这样在任何地方使用它们:

          x = 5
          """ pseudo docstring for x """
          

          epydoc 这样的文档工具可以提取它们并正确格式化它们(与保留在代码格式中的普通注释相反。

          【讨论】:

          • 谢谢 Van Gale,这种类型的答案和上面的“gahooa”是我希望得到的答案。
          【解决方案7】:

          装饰者得到我的投票。你还能在哪里写类似的东西:

          def trace(num_args=0):
            def wrapper(func):
              def new_f(*a,**k):
                print_args = ''
                if num_args > 0:
                  print_args = str.join(',', [str(x) for x in a[0:num_args]])
                print('entering %s(%s)' %(f.__name__,print_args))
                rc = f(*a,**k)
                if rc is not None:
                  print('exiting %s(%s)=%s' %(f.__name__,str(rc)))
                else:
                  print('exiting %s(%s)' %(f.__name__))
                return rc
              return new_f
            return wrapper
          
          @trace(1)
          def factorial(n):
            if n < 2:
              return 1
            return n * factorial(n-1)
          factorial(5)
          

          并获得如下输出:

          entering factorial(5)
          entering factorial(4)
          entering factorial(3)
          entering factorial(2)
          entering factorial(1)
          entering factorial(0)
          exiting factorial(0)=1
          exiting factorial(1)=1
          exiting factorial(2)=2
          exiting factorial(3)=6
          exiting factorial(4)=24
          exiting factorial(5)=120
          

          【讨论】:

          • +1:对于初学者来说,Python 代码不多,但无论如何都可以很酷地使用装饰器。
          【解决方案8】:

          Python 是一种语言,可以这样描述:

          "你可以适应的规则 一个巨大的袋子你的手掌 钩子”。

          python 中的几乎所有内容都遵循相同的简单标准。一切都是可访问的、可更改的和可调整的。语言级别的元素很少。

          以 len(data) 内置函数为例。 len(data) 的工作原理是简单地检查 data.__len__() 方法,然后调用它并返回值。这样,len() 可以作用于任何实现了__len__() 方法的对象。


          从了解类型和基本语法开始:

          1. 动态强类型语言
          2. bool、int、float、string、list、tuple、dict、set
          3. 语句,缩进,“一切都是对象”
          4. 基本函数定义

          然后继续学习 python 的工作原理:

          1. 导入和模块(非常简单)
          2. python 路径 (sys.path)
          3. dir() 函数
          4. __builtins__

          一旦您了解了如何将各个部分组合在一起,请返回并介绍一些更高级的语言功能:

          1. 迭代器
          2. __len__ 这样的覆盖(有很多这样的)
          3. 列表推导和生成器
          4. 类和对象(同样,一旦你知道了一些规则,真的很简单)
          5. python 继承规则

          一旦您对这些项目感到满意(重点是使它们成为 Python 的原因),请查看更具体的项目:

          1. python 中的线程(注意全局解释器锁)
          2. 上下文管理器
          3. 数据库访问
          4. 文件 IO
          5. 套接字
          6. 等等……

          永远不要忘记Python之禅(蒂姆·彼得斯)

          Beautiful is better than ugly.
          Explicit is better than implicit.
          Simple is better than complex.
          Complex is better than complicated.
          Flat is better than nested.
          Sparse is better than dense.
          Readability counts.
          Special cases aren't special enough to break the rules.
          Although practicality beats purity.
          Errors should never pass silently.
          Unless explicitly silenced.
          In the face of ambiguity, refuse the temptation to guess.
          There should be one-- and preferably only one --obvious way to do it.
          Although that way may not be obvious at first unless you're Dutch.
          Now is better than never.
          Although never is often better than *right* now.
          If the implementation is hard to explain, it's a bad idea.
          If the implementation is easy to explain, it may be a good idea.
          Namespaces are one honking great idea -- let's do more of those!
          

          【讨论】:

          • 感谢 gahooa,有帮助的回答!
          • 我喜欢 Zen 的语法颜色 :-)
          • 它应该被编辑,这样杂散的引号就不会搞砸了!
          【解决方案9】:

          从更高级的角度来看,了解 Python 如何在内部使用字典。类、函数、模块、引用都只是字典上的属性。一旦理解了这一点,就很容易理解如何打补丁和使用强大的 __gettattr__、__setattr__ 和 __call__ 方法。

          【讨论】:

            【解决方案10】:

            让我印象特别深刻的两件事是 Python 风格,那就是动态类型和 Python 中使用的各种类型的列表,尤其是元组。

            Python 对列表的痴迷可以说是 LISP-y,但它有自己独特的风格。像这样的一行:

            return HandEvaluator.StraightFlush, (PokerCard.longFaces[index + 4], 
              PokerCard.longSuits[flushSuit]), []
            

            甚至

            return False, False, False
            

            只是看起来像 Python,没有别的。 (从技术上讲,你也会在 Lua 中看到后者,但 Lua 总体上是 Python 风格的。)

            【讨论】:

              【解决方案11】:

              此页面涵盖了所有主要的 python 习语:http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html

              【讨论】:

                【解决方案12】:

                与列表使用相关的所有内容。
                理解、生成器等。

                【讨论】:

                  猜你喜欢
                  • 2011-07-17
                  • 2023-03-11
                  • 2023-04-09
                  • 1970-01-01
                  • 2020-07-28
                  • 2012-03-04
                  • 2014-03-11
                  • 2011-05-12
                  • 2018-02-27
                  相关资源
                  最近更新 更多