programing

파이썬 메소드 오버라이드, 서명이 중요합니까?

megabox 2023. 7. 28. 21:54
반응형

파이썬 메소드 오버라이드, 서명이 중요합니까?

내가 가지고 있다고 치자.

class Super():
  def method1():
    pass

class Sub(Super):
  def method1(param1, param2, param3):
      stuff

이거 맞는건가요?메소드1에 대한 호출은 항상 하위 클래스로 갑니까?나의 계획은 각각 2개의 하위 클래스가 다른 매개 변수로 method1을 재정의하는 것입니다.

Python에서 메소드는 클래스에 연결된 사전의 키-값 쌍일 뿐입니다.기본 클래스에서 클래스를 파생할 때 메서드 이름이 먼저 파생된 클래스 사전을 조사한 다음 기본 클래스 사전을 조사한다는 의미입니다.메서드를 "재지정"하려면 파생 클래스에서 메서드를 다시 선언하기만 하면 됩니다.

그렇다면, 파생 클래스에서 재정의된 메서드의 서명을 변경하면 어떻게 될까요?호출이 파생 인스턴스에 있으면 모든 것이 올바르게 작동하지만 기본 인스턴스에서 호출을 하면 기본 클래스가 동일한 메서드 이름에 대해 다른 서명을 사용하기 때문에 오류가 발생합니다.

그러나 파생 클래스 메소드에 추가 매개 변수가 있고 메소드 호출이 기본적으로 오류 없이 수행되기를 원하는 시나리오가 자주 있습니다.이것은 "Liskov 대체 원리"(또는 LSP)라고 불리며, 만약 사람이 기본 인스턴스에서 파생 인스턴스로 전환하거나 그 반대의 경우에는 코드를 수정할 필요가 없습니다.Python에서 이를 수행하려면 다음 기술을 사용하여 기본 클래스를 설계해야 합니다.

class Base:
    # simply allow additional args in base class
    def hello(self, name, *args, **kwargs):
        print("Hello", name)

class Derived(Base):
      # derived class also has unused optional args so people can
      # derive new class from this class as well while maintaining LSP
      def hello(self, name, age=None, *args, **kwargs):
          super(Derived, self).hello(name, age, *args, **kwargs) 
          print('Your age is ', age)

b = Base()
d = Derived()

b.hello('Alice')        # works on base, without additional params
b.hello('Bob', age=24)  # works on base, with additional params
d.hello('Rick')         # works on derived, without additional params
d.hello('John', age=30) # works on derived, with additional params

위에 인쇄:

안녕 앨리스안녕 밥안녕 릭나이 없음안녕 존당신의 나이는 30살입니다.
. 이 코드로 재생

파이썬은 이것을 허용하겠지만, 만약에.method1()이는 외부 코드에서 실행되도록 되어 있으므로 LSP를 위반하므로 항상 제대로 작동하지는 않습니다.

기본 인수를 사용해도 괜찮으면 다음과 같은 작업을 수행할 수 있습니다.

>>> class Super():
...   def method1(self):
...     print("Super")
...
>>> class Sub(Super):
...   def method1(self, param1="X"):
...     super(Sub, self).method1()
...     print("Sub" + param1)
...
>>> sup = Super()
>>> sub = Sub()
>>> sup.method1()
Super
>>> sub.method1()
Super
SubX

파이썬에서 모든 클래스 메소드는 "가상"(C++ 측면에서)입니다.코드의 경우, 당신이 전화하고 싶다면,method1()슈퍼 클래스에서, 그것은 다음과 같아야 합니다.

class Super():
    def method1(self):
        pass

class Sub(Super):
    def method1(self, param1, param2, param3):
       super(Sub, self).method1() # a proxy object, see http://docs.python.org/library/functions.html#super
       pass

그리고 방법 서명은 중요합니다.다음과 같은 메서드를 호출할 수 없습니다.

sub = Sub()
sub.method1() 

작동합니다.

>>> class Foo(object):
...   def Bar(self):
...     print 'Foo'
...   def Baz(self):
...     self.Bar()
... 
>>> class Foo2(Foo):
...   def Bar(self):
...     print 'Foo2'
... 
>>> foo = Foo()
>>> foo.Baz()
Foo
>>> 
>>> foo2 = Foo2()
>>> foo2.Baz()
Foo2

그러나 일반적으로 권장되지는 않습니다.S를 보세요.로트의 대답:이름이 같고 인수가 다른 메서드는 코드 냄새입니다.

언급URL : https://stackoverflow.com/questions/6034662/python-method-overriding-does-signature-matter

반응형