이 곳에서는 조심하세요.

저자:이리단, 2016-12-29 13:46:12, 업데이트:

이 곳에서는 조심하세요.

python是一门非常有趣的语言。它提供了许多非常方便的标准库和许多内置命令是我们轻松完成任务.但是好东西太多了就有选择恐惧症了,以至于我们不能很好第利用这个标准库和它的基本机构。下面列出了一些对python新手来说很简单有效的陷阱。

  • Python의 버전을 무시합니다.

    이것은 StackOverflow에서 끊임없이 제기되는 문제입니다. 타인의 컴퓨터에서 완벽한 코드를 실행할 때 오류를 보기는 어떤 경험인지 확인하는 것이 좋습니다.

    $ python --version
    Python 2.7.9
    

    python 버전 관리

    pyenv는 좋은 파이썬 버전 관리 도구이다. 불행히도 그것은 단지 *nix 시스템에서 실행된다. Mac OS에서, 당신은 간단하게 brew install pyenv를 사용하여 설치할 수 있습니다.

  • 한 줄의 코드로 모든 문제를 해결하는 것

    많은 사람들이 내가 한 줄의 코드로 모든 문제를 해결했다고 자랑하지만, 그들의 코드는 정상적으로 작성된 것보다 더 비효율적이기도 하고 읽기 힘들기도 하고 모호하기도 합니다. 예를 들어:

    l = [m for a, b in zip(this, that) if b.method(a) != b for m in b if not m.method(a, b) and reduce(lambda x, y: a + y.method(), (m, a, b))]
    

    사실, 위의 코드는 제가 직접 작성한 것입니다. 하지만 저는 많은 사람들이 실제로 그렇게 하는 것을 보았습니다. 만약 여러분이 단순히 리스트나 세트에 무언가를 추가함으로써 복잡한 문제를 해결하는 방법을 보여주면, 여러분은 돈을 잃게 될 가능성이 있습니다.

    한 줄의 코드 컨트롤은 때로는 매우 똑똑해 보이지만 큰 성과가 아닙니다. 좋은 코드는 간결하지만 효율성과 읽기 편성에 더 중점을 둡니다.

  • 실수로 초기화된 세트

    这是一个更加微妙的问题,有时候会让你措手不及。set推导式起来有点像list推导式.

    >>> { n for n in range(10) if n % 2 == 0 }
    {0, 8, 2, 4, 6}
    >>> type({ n for n in range(10) if n % 2 == 0 })
    

    위의 예시에서 이것을 보여줍니다. ▲set은 컨테이너에 있는 리스트와 비슷합니다. 그 차이점은 세트가 반복값이 없고 무질서하다는 것이다. 보통 사람들은 {}를 빈 세트로 생각하지만, 그렇지 않다. 그것은 빈 디크트이다.

    >>> {}
    {}
    >>> type({})
    

    그래서 만약 우리가 빈 집합을 초기화하고 싶다면,

    >>> set()
    set()
    >>> type(set())
    

    공백 세트는 세트로 표시될 수 있지만, 요소를 포함하는 세트가 세트로 정의되는 것처럼 보입니다.

  • GIL에 대한 오해

    GIL (글로벌 인터프리터 잠금) 은 하나의 파이썬 프로그램에서 오직 하나의 스레드가 한 번에 실행될 수 있음을 의미합니다. 이것은 우리가 하나의 스레드를 만들 수 없으며, 그것이 병렬로 실행될 것으로 기대할 수 없다는 것을 의미합니다. 파이썬 인터프리터는 실제로 다른 실행 스레드를 빠르게 전환하는 것입니다. 그러나 이것은 매우 간단한 버전입니다. 많은 경우에 프로그램이 C 확장된 라이브러리를 사용하는 것과 같이 병렬로 실행됩니다. 그러나 파이썬 코드가 실행되는 동안 대부분의 경우 병렬로 실행되지 않습니다. 즉, 파이썬에서 스레드는 자바 또는 c++에서와 같지 않습니다.

    많은 사람들이 파이썬을 위해 이 모든 것이 실제 스레드라고 변명하려고 시도할 것입니다. 3 이것은 사실이지만, 파이썬이 스레드를 처리하는 방식이 당신이 기대하는 방식과 다르다는 사실을 바꿀 수는 없습니다. 루비에서도 비슷한 상황이 ((또한 인터프리터 잠금도 있습니다)).

    정해진 해결책은 멀티프로세싱 모듈을 사용하는 것이다. 멀티프로세싱 모듈이 제공하는 프로세스는 기본적으로 차이를 잘 덮을 수 있다. 그러나, 차이점은 스레드 비용보다 훨씬 높다. 따라서 병렬 운영은 항상 좋지 않다.

    그러나 이 문제는 모든 파이썬 프로그램이 겪는 것은 아닙니다. 파이파이-stm는 GIL에 영향을 받지 않는 파이썬 구현의 한 예입니다. 다른 플랫폼에 구축된 구현은 JVM (Jython) 또는 CLR (IronPython) 처럼 GIL 문제가 없습니다.

    간단히 말해서, 스레드 클래스를 사용할 때 조심하십시오. 당신은 당신이 원하는 것이 아닐 수 있습니다.

  • 오래된 스타일 클래스를 사용함

    파이썬 2에서는 두 가지 유형의 클래스가 있습니다. 구형 과 새 스타일 . 만약 당신이 파이썬 3를 사용한다면, 당신은 기본 의 새 스타일 을 사용하고 있습니다. 파이썬 2 클래스에서 새 스타일 을 사용하는 것을 보장하기 위해, 당신은 object 또는 당신이 만든 새로운 클래스를 상속해야 합니다. 즉, 당신의 기본 클래스는 항상 built-in int 또는 list의 클래스를 상속해야 합니다.

    class MyNewObject(object): # stuff here
    

    이 새로운 클래스 은 오래된 클래스에서 발견된 몇 가지 기본적인 문제를 해결합니다.

  • 잘못된 반복

    이 오류는 신규 사용자들에게 매우 흔합니다.

    for name_index in range(len(names)):
      print(names[name_index])
    

    랭을 사용할 필요가 없는 것은 분명합니다. 실제로는 매우 간단한 문장으로 목록을 돌아볼 수 있습니다.

    for name in names:
       print(name)  
    

    또한, 다른 많은 도구들이 있습니다. 예를 들어, zip는 두 개의 목록을 탐색하는 데 사용할 수 있습니다.

    for cat, dog in zip(cats, dogs):
       print(cat, dog)
    

    만약 우리가 인덱스와 값 목록 변수를 고려한다면, 우리는 enumerate를 사용할 수 있습니다.

    for index, cat in enumerate(cats):
       print(cat, index)
    

    이터툴스에는 다양한 기능이 있습니다. 이터툴스에는 당신이 원하는 기능이 있다면 쉽게 얻을 수 있습니다. 하지만 그것을 사용하기 위해 너무 많이 사용하지 마십시오.

    itertools의 오용으로 StackOverflow의 한 대신이 문제를 해결하는 데 많은 시간을 보냈습니다.

    기본 변수를 사용했습니다.

    이 글은 제가 본 것 중 많은 것 중 하나입니다.

    def foo(a, b, c=[]):
       # append to c
       # do some more stuff
    

    변수를 사용하지 말고 다음을 사용하십시오.

    def foo(a, b, c=None):
     if c is None:
       c = []
       # append to c
       # do some more stuff 
    

    이 문제를 이해하기 위해 아래의 예제를 통해 쉽게 이해할 수 있습니다.

    In[2]: def foo(a, b, c=[]):
    ...     c.append(a)
    ...     c.append(b)
    ...     print(c)
    ...
    In[3]: foo(1, 1)
    [1, 1]
    In[4]: foo(1, 1)
    [1, 1, 1, 1]
    In[5]: foo(1, 1)
    [1, 1, 1, 1, 1, 1]
    

    동일한 c가 반복적으로 호출될 때마다 이 함수를 호출한다. 이것은 매우 불필요한 결과를 초래할 수 있다.


더 많은