루비와 파이썬 모두에서 원숭이 패치가 허용된다면 왜 루비에서 더 논란이 되는가?

StackOverflow https://stackoverflow.com/questions/717506

문제

많은 토론에서 사람들이 언어에 대한 예약을 표현한 루비에 대해 들었습니다. 원숭이 패치 문제는 주요 관심사 중 하나로 제기됩니다.

그러나 파이썬 언어로도 허용되지만 파이썬의 맥락에서 동일한 주장을 거의 듣지 않습니다.

왜이 차이가 있습니까?

Python에는이 기능의 위험을 최소화하기 위해 다양한 유형의 보호 장치가 포함되어 있습니까?

도움이 되었습니까?

해결책

루비를 맛보고 (그리고 좋아하는) 파이썬 프로그래머로서, 나는 파이썬이 인기를 얻기 시작했을 때와 비슷한 아이러니 한 것이 있다고 생각합니다.

C와 Java 프로그래머는 Python을 '강타'로, 실제 언어가 아니며 유형의 역동적 인 특성은 위험 할 것이며 사람들이 '나쁜'코드를 만들 수 있다고 진술했습니다. Python이 점점 인기를 얻었고, 빠른 개발 시간의 장점은 덜 장황한 구문은 말할 것도없이 분명해졌습니다.

// Java
Person p = new Person();
# Python
p = Person()

우리는 이후 버전의 Java에 더 역동적 인 기능이 나타나기 시작했습니다. 오토 옥싱 및 -박스 잉은 프리미티브를 다루는 것이 덜 번거 롭게 만들고 제네릭은 한 번 코딩하여 여러 유형에 적용 할 수 있습니다.

루비의 주요 유연한 특징 중 하나 인 원숭이 패치 (Monkey Patching) 중 하나를 보았습니다. 파이썬 군중에 의해 위험한 것으로 선전되었습니다. 올해 Ruby를 학생들에게 가르치기 시작한 후, 기존 수업, 심지어 시스템의 일부인 수업을 '고정'할 수 있다는 것은 매우 강력하다고 생각합니다.

물론, 당신은 심하게 망칠 수 있고 당신의 프로그램이 충돌 할 수 있습니다. 나는 C에서도 쉽게 segfault 할 수 있습니다. 그리고 Java 앱은 불타는 죽음을 죽일 수 있습니다.

진실은, 나는 원숭이 패치를 동적 및 메타 프로그래밍의 다음 단계로 본다는 것입니다. Smalltalk 이후에 있었기 때문에 재미있었습니다.

다른 팁

Python에서 실행되지 않은 기술은 부분적으로 Python의 "Core"클래스 (C에서 구현 된 클래스)가 실제로 수정할 수 없기 때문입니다. 반면에, 루비에서는 내부적으로 구현되는 방식 (더 나은 것이 아니라 다르지 않음)으로 인해 동적으로 수정할 수 있습니다.

철학적으로, 그것은 Python 커뮤니티 내에서 눈살을 찌푸리는 경향이 있으며, 루비 세계에서는 분명히 덜 덜합니다. 왜 당신이 그것이 더 논란의 여지가 있다고 주장하는지 모르겠습니다 (권위있는 참조와 연결할 수 있습니까?) - 저의 경험은 원숭이 패치가 가능한 결과를 알고 있어야하는 경우 원숭이 패치가 허용되는 기술이라는 것입니다.

언어는이를 허용 할 수 있지만 공동체는 연습을 용납하지 않습니다. 원숭이 가립은 어느 언어로든 용납되지는 않지만, 그것이 사용하는 오픈 클래스의 형태는 수업을 원숭이로 만들기가 매우 쉽고, 이로 인해,이 때문에, 그것을 사용하기 때문에 루비에서 더 자주들을 수 있습니다. 루비 커뮤니티에서는 더 수용 가능하지만 여전히 눈살을 찌푸 렸습니다.. Monkeypatching은 단순히 파이썬에서 널리 퍼지거나 쉽지 않기 때문에 해당 커뮤니티에서 동일한 주장을 듣지 못합니다. 파이썬은 루비가 연습을 막기 위해하지 않는 일을하지 않습니다.

루비에서 더 자주 듣고 읽는 이유는 루비에서 이것입니다.

class MyClass
  def foo
    puts "foo"
  end
end
class MyClass
  def bar
    puts "bar"
  end
end

두 가지 방법이 포함 된 수업을 제공합니다. foo 그리고 bar, 파이썬에서는 이것 :

class MyClass:
    def foo(self):
        print "foo"
class MyClass:
    def bar(self):
        print "bar"

메소드 만 포함하는 수업을 남길 것입니다. bar, 클래스의 재정의로서 이전 정의를 완전히 클로버합니다. Python의 monkeypatch를 위해서는 실제로 다음을 작성해야합니다.

class MyClass:
    def foo(self):
        print "foo"
def bar(self):
    print "bar"
MyClass.bar = bar

루비 버전보다 어렵습니다. 그것만으로도 루비 코드는 Python 코드보다 Monkeypatch를 훨씬 쉽게 만듭니다.

"Python에는이 기능의 위험을 최소화하기 위해 다양한 유형의 보호 장치가 포함되어 있습니까?"

예. 공동체는 그것을 거부합니다. 보호 조치는 전적으로 사회적입니다.

실제로 파이썬에서는 기본 유형을 수정하기가 조금 더 어렵습니다.

예를 들어, 정수를 재정의한다고 상상해보십시오.

루비:

class Fixnum 
   def *(n)
      5 
   end 
end

이제 2*2는 5를 생산합니다.

파이썬 :

>>> class int(int):
    def __mul__(self, x):
        return 5


>>> 2*2
4
>>> int(2)*int(2)
5

파이썬에서 문자 그대로 ("", {}, 1.0, 등)는 표준 클래스의 인스턴스를 만듭니다. 만족을 만들려고 시도하고 네임 스페이스에서 해당 클래스를 재정의했습니다.

당신이 의도 한 방식으로 작동하지 않을 것입니다.

class str():
    # define your custom string type
    ...

a = "foo"      # still a real Python string
a = str("foo") # only this uses your custom class

원숭이 패치는 마지막 솔루션으로 만 사용해야한다고 생각합니다.

일반적으로 Python 프로그래머는 클래스 또는 메소드가 어떻게 작동하는지 알고 있습니다. 그들은 클래스 XXX가 특정한 방식으로 일을하고 있다는 것을 알고 있습니다.

원숭이 패치를 수업이나 방법을 패치 할 때, 당신은 그것이 행동을 바꾸고 있습니다. 이 클래스를 사용하는 다른 Python 프로그래머는 해당 클래스가 다르게 행동하는 경우 매우 놀랄 수 있습니다.

일을하는 정상적인 방법은 서브 클래싱입니다. 그렇게하면 다른 프로그래머는 다른 객체를 사용하고 있음을 알고 있습니다. 원하는 경우 원래 클래스 또는 하위 클래스를 사용할 수 있습니다.

파이썬에서 원숭이 패치를하고 싶다면 내장 유형 (int, float, str)을 수정하지 않는 한 비교적 쉽습니다.

class SomeClass:
    def foo(self):
        print "foo"

def tempfunc(self):
    print "bar"
SomeClass.bar = tempfunc
del tempfunc

이것은 막대 방법을 someclass에 추가하고 해당 클래스의 기존 인스턴스조차 해당 주입 된 방법을 사용할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top