728x90
728x90

self.function(param)과 function(self, param)의 차이점

들어가며

  • PyQt를 이용하여 개발을 할 때, 언제 @self.function(param)@ 또는 @function(self, param)@를 써야할지 헷갈릴 때가 있다.
  • 이 둘의 차이점에 대해 정리해본다.

 

 

self

개념

  • 파이썬 클래스의 인스턴스 메서드에서 현재 객체 자신을 참조하기 위한 첫 번째 매개변수
  • 클래스의 인스턴스(객체) 자신을 참조하는 변수
    • 클래스 내에서 정의된 메서드가 호출될 때 자동으로 해당 메서드가 속한 객체를 가리키도록 한다.
  • 클래스 객체 지향 프로그래밍(OOP)에서 매우 중요한 개념
  • 메서드 내에서 객체의 속성이나 다른 메서드에 접근할 때 사용

 

@self@는 메서드 내에서 객체의 속성과 다른 메서드에 접근할 수 있게 해준다.

 

역할

  • 객체가 가지고 있는 데이터(속성)에 접근하고 수정할 수 있다.
  • 클래스 내의 다른 메서드를 호출할 때 사용된다.
  • 객체의 상태를 메서드 간에 유지하고 관리할 수 있다.

 

사용 방법

  • 아래의 예제 코드를 통해 사용 방법을 정리해본다.
class MyClass:
    def __init__(self, value):
        self.value = value  # 객체의 속성에 접근하여 초기화

    def display_value(self):
        print(self.value)   # self를 사용하여 속성에 접근

 

생성자 메서드(@__init__@)는 객체가 생성될 때 호출된다.

인스턴스 메서드(@display_value@)는 @self.value@를 사용하여 객체의 @value@ 속성에 접근하고 출력한다.

 

  • 다음과 같이 인스턴스를 생성하고 메서드를 호출할 수 있다.
obj = MyClass(10)       # 객체 생성. __init__ 메서드 호출
obj.display_value()     # display_value 메서드 호출 (10)

 

⇒ @obj.display_value()@를 호출하면, 파이썬은 내부적으로 @MyClass.display_value(obj)@를 호출한다. (즉, @self@는 자동으로 현재 객체 @obj@를 참조하게 된다.)

 

self 사용의 중요성

  • 여러 객체가 같은 클래스로부터 생성되더라도, 각 객체는 고유한 @self@를 가지므로 서로의 상태를 독립적으로 유지할 수 있다.
  • @self@를 사용함으로써 메서드 내에서 어떤 속성이나 메서드가 객체에 속한 것인지를 명확하게 구분할 수 있다.
  • 상속받은 클래스에서 @self@를 사용하면 부모 클래스속성메서드에 접근할 수 있어 유연한 설계가 가능하다.

 

자주 하는 실수

① @self@를 매개변수에 포함시키지 않는 경우

  • 클래스 안에서 메서드의 매개변수에 @self@를 포함시키지 않는 경우이다.
class MyClass:
    def display_value():
        print(self.value)  # 오류 발생

obj = MyClass()
obj.display_value()  # TypeError: display_value() takes 0 positional arguments but 1 was given

 

  • 메서드 정의 시, 반드시 첫 번째 매개변수로 @self@를 포함해야 한다.
class MyClass:
    def display_value(self):
        print(self.value)

 

② @self@를 메서드 호출 시 전달하는 경우

class MyClass:
    def display_value(self):
        print(self.value)

obj = MyClass()
obj.display_value(obj)  # display_value() takes 1 positional argument but 2 were given

 

  • 메서드를 호출할 때, @self@를 직접 전달하지 않는다.
    • 객체가 자동으로 @self@를 전달한다.
obj.display_value()

 

③ @self@를 속성 이름으로 사용하는 경우

  • @self@는 객체 자신을 참조하는 변수이므로, 속성 이름으로 사용하는 것은 혼란을 초래할 수 있다.
  • 예를 들어,@ self.self@와 같이 사용하면 코드의 가독성이 떨어지고 이해하기 어려워진다.

 

@self@와 클래스 메서드, 정적 메서드

  • 파이썬 클래스에는 인스턴스 메서드(Instance Method) 외에도 클래스 메서드(Class Method)와 정적 메서드(Static Method)가 있다. 이들 메서드는 @self@ 대신 다른 매개변수를 사용한다.

 

클래스 메서드 (@classmethod@)

  • 클래스 자체첫 번째 매개변수로 받는다.
  • 보통 @cls@라는 이름을 사용한다.
class MyClass:
    class_variable = 0

    @classmethod
    def increment_class_variable(cls):
        cls.class_variable += 1

 

정적 메서드(@staticmethod@)

  • 객체나 클래스에 접근할 필요가 없는 메서드
  • @self@나 @cls@를 사용하지 않는다.
class MyClass:
    @staticmethod
    def greet():
        print("Hello!")

 

정리

  • @self@는 파이썬 클래스의 인스턴스 메서드에서 현재 객체 자신을 참조하는 첫 번째 매개변수이다.
  • @self@를 사용하여 객체의 속성과 다른 메서드에 접근할 수 있다.
  • @self@는 관례적인 이름으로, 다른 이름을 사용할 수도 있지만 권장되지 않는다.
  • 메서드를 정의할 때는 항상 @self@를 첫 번째 매개변수로 포함해야 하며, 메서드를 호출할 때는 @self@를 직접 전달하지 않는다.
  • 클래스 메서드와 정적 메서드는 각각 @cls@와 매개변수를 사용하여 객체와 독립적으로 동작한다

 

self.function(param) vs. function(self, param)

self.function(params)

  • @function@이 현재 객체(@self@)의 메서드임을 나타낸다.
  • 메서드는 클래스 내에 정의되며, 호출 시 @self@ 인스턴스가 자동으로 첫 번째 인자로 전달된다.
    • @self.function(param)@ → @function(self, param)@

 

예제 코드
  • @self.random_function(content)@을 호출하면,@random_function@ 메서드가 현재 인스턴스(@self@)와 함께 @content@를 인자로 받아 실행된다.
class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.setup_ui()

    def setup_ui(self):
        content = "Hello, PyQt!"
        self.random_function(content)  # 메서드 호출

    def random_function(self, content):
        print(content)

 

function(self, param)

  • @function@이 독립적인 함수이며, 현재 객체(@self@)명시적으로 첫 번째 인자로 전달하는 방식
  • 함수는 클래스 외부에 정의되거나 클래스 내부에 있지만 메서드가 아닌 함수로 정의되어 있을 수 있다.
  • 호출 시 모든 필요한 인자를 명시적으로 전달해야 한다.

 

예제 코드
  • @random_function(self, content)@을 호출하면, @random_function@ 함수가 현재 인스턴스(@self@)와 @content@를 인자로 받아 실행한다.
# 클래스 외부에서 함수 정의
def random_function(instance, content):
    print(content)

class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.setup_ui()

    def setup_ui(self):
        content = "Hello, PyQt!"
        random_function(self, content)  # 함수 호출

 

주요 차이점

바인딩 방식

  • @self.function(param)@은 @function@이 클래스의 메서드로 바인딩되어 있어 @self@가 자동으로 전달된다.
  • @function(self, param)@은 @function@이 독립적인 함수이므로 @self@를 명시적으로 전달해야 한다.

 

정의 위치

  • 메서드클래스 내부에 @def@ 키워드를 사용하여 정의된다.
  • 함수클래스 외부에 정의되거나, 클래스 내부에 있지만 메서드가 아닌 일반 함수로 정의될 수 있다.

 

코드 구조 및 가독성

  • 메서드를 사용하면 관련 기능을 클래스 내부에 깔끔하게 묶을 수 있어 코드의 가독성과 유지보수성이 향상된다.
  • 독립된 함수를 사용할 경우, 특정 기능을 여러 클래스에서 재사용하고자 할 때 유용할 수 있다.

 

선택 기준

  • 클래스의 상태에 접근해야 할 경우, 메서드를 사용하는 것이 적합하다.
    • 메서드는 클래스의 속성과 다른 메서드에 쉽게 접근할 수 있다.
  • 독립적인 기능을 구현할 경우, 함수로 정의하고 @self@를 인자로 전달하는 것이 적합할 수 있다.
    • 특히 여러 클래스에서 공통으로 사용할 수 있는 유틸리티 함수일 경우 유리하다.

 

정리

  • @self.function(param)@은 클래스메서드를 호출하는 방식으로, @self@가 암묵적으로 전달된다.
  • @function(self, param)@은 독립적인 함수를 호출하는 방식으로, @self@를 명시적으로 전달해야 한다.

 

참고 사이트

 

9. Classes

Classes provide a means of bundling data and functionality together. Creating a new class creates a new type of object, allowing new instances of that type to be made. Each class instance can have ...

docs.python.org

 

728x90
728x90