Python에서 객체 지향 프로그래밍(OOP)의 기본을 알아보세요: 클래스, 객체, 인스턴스 메서드, 속성 등을 살펴보세요!
객체 지향 프로그래밍은 강력한 애플리케이션을 작성하는 데 널리 사용되는 개념입니다. 데이터 과학자로서 여러분은 데이터를 처리하는 애플리케이션을 작성해야 하며, 그 외에도 다양한 작업을 해야 합니다. 이 튜토리얼에서는 Python에서 객체 지향 프로그래밍의 기본을 알아봅니다. 다음을 배우게 됩니다.
- 클래스를 만드는 방법
- 객체 인스턴스화
- 클래스에 속성 추가
- 클래스 내에서 메서드 정의하기
- 메서드에 인수 전달
- 파이썬에서 OOP를 금융에 사용하는 방법
OOP: 소개
객체 지향 프로그래밍은 다른 디자인 패턴에 비해 몇 가지 장점이 있습니다. 개발이 더 빠르고 저렴하며 소프트웨어 유지 관리가 더 좋습니다. 이는 결과적으로 더 높은 품질의 소프트웨어로 이어지며, 이는 새로운 메서드와 속성으로 확장 가능합니다. 그러나 학습 곡선은 더 가파릅니다. 이 개념은 초보자에게는 너무 복잡할 수 있습니다. 계산적으로 OOP 소프트웨어는 더 느리고 더 많은 줄의 코드를 작성해야 하기 때문에 더 많은 메모리를 사용합니다.
객체 지향 프로그래밍은 명령문을 사용하여 프로그램의 상태를 변경하는 명령형 프로그래밍 패러다임을 기반으로 합니다. 프로그램이 어떻게 작동해야 하는지 설명하는 데 중점을 둡니다. 명령형 프로그래밍 언어의 예로는 C, C++, Java, Go, Ruby 및 Python이 있습니다. 이는 컴퓨터 프로그램이 어떻게 수행해야 하는지에 초점을 맞추고 방법을 지정하지 않는 선언형 프로그래밍과 대조됩니다. 예로는 SQL 및 XQuery와 같은 데이터베이스 쿼리 언어가 있는데, 여기서는 컴퓨터에 어디에서 어떤 데이터를 쿼리해야 하는지만 알려주고 지금은 어떻게 해야 하는지 알려줍니다.
OOP는 객체와 클래스의 개념을 사용합니다. 클래스는 객체에 대한 ‘청사진’으로 생각할 수 있습니다. 이러한 객체는 고유한 속성(소유하는 특성)과 메서드(수행하는 동작)를 가질 수 있습니다.
OOP 예제
클래스의 한 예는 클래스입니다 Dog. 그것을 특정한 개나 자신의 개로 생각하지 마십시오. 우리는 개가 무엇 이고 무엇을 할 수 있는지 , 일반적으로 설명하고 있습니다. 개는 일반적으로 name와 를 가지고 있습니다 age. 이것들은 인스턴스 속성입니다. 개는 또한 bark; 이것은 메서드입니다.
특정한 개에 대해 이야기할 때, 프로그래밍에서 객체가 있을 것입니다. 객체는 클래스의 인스턴스입니다. 이것이 객체 지향 프로그래밍의 기본 원리입니다. 예를 들어, 제 개 오지는 클래스에 속합니다. Dog그의 속성은 name = ‘Ozzy’과 입니다 age = ‘2’. 다른 개는 다른 속성을 가질 것입니다.
파이썬에서의 객체 지향 프로그래밍
파이썬은 객체 지향적인가?
Python은 OOP를 지원하는 훌륭한 프로그래밍 언어입니다. 이를 사용하여 속성과 메서드가 있는 클래스를 정의한 다음 호출합니다. Python은 Java, C++ 또는 R과 같은 다른 프로그래밍 언어에 비해 여러 가지 이점을 제공합니다. 고수준 데이터 유형을 갖춘 동적 언어입니다. 즉, Java 또는 C++보다 개발이 훨씬 빠릅니다. 프로그래머가 변수 및 인수 유형을 선언할 필요가 없습니다. 또한 Python은 초보자가 이해하고 배우기 쉽고 코드가 더 읽기 쉽고 직관적입니다.
클래스를 만드는 방법
Python에서 클래스를 정의하려면 class키워드를 사용하고, 그 뒤에 클래스 이름과 콜론을 붙입니다. 클래스 내부에서 메서드는 . __init__로 정의해야 합니다 def. 이것은 나중에 객체를 인스턴스화하는 데 사용할 수 있는 초기화 프로그램입니다. Java의 생성자와 비슷합니다. __init__항상 존재해야 합니다! 하나의 인수를 취합니다. self는 객체 자체를 참조합니다. 메서드 내부에서는 pass현재 키워드를 사용하는데, Python이 거기에 무언가를 입력할 것으로 예상하기 때문입니다. 올바른 들여쓰기를 사용하는 것을 잊지 마세요!
class Dog: def __init__(self): pass |
참고 : Python에서는 C++ 또는 Java self와 동일합니다 .this
이 경우, (대부분 비어 있는) Dog클래스가 있지만 아직 객체가 없습니다. 하나 만들어 봅시다!
객체 인스턴스화
객체를 인스턴스화하려면 클래스 이름을 입력하고 그 뒤에 두 개의 괄호를 붙입니다. 이것을 변수에 할당하여 객체를 추적할 수 있습니다.
ozzy = Dog() |
그리고 인쇄하세요:
print(ozzy) <__main__.Dog object at 0x111f47278> |
클래스에 속성 추가
를 인쇄한 후 ozzy, 이 객체가 개라는 것이 분명해졌습니다. 하지만 아직 속성을 추가하지 않았습니다. 클래스에 Dog이름과 나이를 지정하려면 다음과 같이 다시 작성해 보겠습니다.
class Dog: def __init__(self, name, age): self.name = name self.age = age |
이제 함수가 self: name와 age. 뒤에 두 개의 인수를 취하는 것을 볼 수 있습니다. 그런 다음 각각 self.name와 에 할당됩니다 self.age. 이제 ozzy이름과 나이를 사용하여 새 객체를 만들 수 있습니다.
ozzy = Dog(“Ozzy”, 2) |
파이썬에서 객체의 속성에 접근하려면 점 표기법을 사용할 수 있습니다. 이는 객체의 이름을 입력한 다음 점과 속성의 이름을 입력하여 수행됩니다.
print(ozzy.name) print(ozzy.age) Ozzy 2 |
이것은 더 정교한 문장으로 결합될 수도 있습니다:
print(ozzy.name + ” is ” + str(ozzy.age) + ” year(s) old.”) Ozzy is 2 year(s) old. |
str()여기서 함수는 정수인 속성을 문자열로 변환하여 함수 내에서 사용할 수 있도록 하는 데 age사용 됩니다 print().
클래스에서 메서드 정의하기
이제 클래스가 생겼으니 Dog이름과 나이가 있는데, 이를 추적할 수 있지만 실제로는 아무것도 하지 않습니다. 여기서 인스턴스 메서드가 등장합니다. 이제 메서드를 포함하도록 클래스를 다시 작성할 수 있습니다 . 키워드가 어떻게 다시 사용되는지, 그리고 인수가 어떻게 사용 bark()되는지 주목하세요 .def self
class Dog: def __init__(self, name, age): self.name = name self.age = age def bark(self): print(“bark bark!”) |
bark이제 새 객체를 인스턴스화한 후 점 표기법을 사용하여 메서드를 호출할 수 있습니다 . ozzy메서드는 화면에 “bark bark!”를 인쇄해야 합니다. .의 괄호(중괄호)에 주목하세요 .bark(). 이는 메서드를 호출할 때 항상 사용됩니다. 이 경우 메서드가 bark()인수를 취하지 않으므로 비어 있습니다.
ozzy = Dog(“Ozzy”, 2) ozzy.bark() bark bark! |
이전에 인쇄한 것을 기억하십니까 ozzy? 아래 코드는 이제 Dog메서드로 클래스 에서 이 기능을 구현합니다 doginfo(). 그런 다음 다른 속성을 가진 일부 객체를 인스턴스화하고 해당 객체에서 메서드를 호출합니다.
class Dog: def __init__(self, name, age): self.name = name self.age = age def bark(self): print(“bark bark!”) def doginfo(self): print(self.name + ” is ” + str(self.age) + ” year(s) old.”) ozzy = Dog(“Ozzy”, 2) skippy = Dog(“Skippy”, 12) filou = Dog(“Filou”, 8) ozzy.doginfo() skippy.doginfo() filou.doginfo() Ozzy is 2 year(s) old. Skippy is 12 year(s) old. Filou is 8 year(s) old. |
보시다시피, doginfo()점 표기법으로 객체에서 메서드를 호출할 수 있습니다. 이제 응답은 Dog메서드를 호출하는 객체에 따라 달라집니다.
개는 나이가 들기 때문에 그에 맞게 나이를 조절해 주시면 좋겠습니다. 오지가 막 3살이 되었으니, 나이를 바꿔 봅시다.
ozzy.age = 3 print(ozzy.age) 3 |
속성에 새 값을 할당하는 것만큼 쉽습니다. birthday()Dog 클래스에서 메서드로 구현할 수도 있습니다.
class Dog: def __init__(self, name, age): self.name = name self.age = age def bark(self): print(“bark bark!”) def doginfo(self): print(self.name + ” is ” + str(self.age) + ” year(s) old.”) def birthday(self): self.age +=1 ozzy = Dog(“Ozzy”, 2) print(ozzy.age) 2 ozzy.birthday() print(ozzy.age) 3 |
이제 수동으로 강아지의 나이를 변경할 필요가 없습니다. 강아지의 생일이 되면 birthday()메서드를 호출하기만 하면 됩니다.
메서드에 인수 전달
영어: 당신은 우리 개에게 친구가 있기를 원합니다. 모든 개가 사교적인 것은 아니므로 이것은 선택 사항이어야 합니다. 아래의 메서드를 살펴보세요 . 평소처럼 , 를 인수로 setBuddy()사용합니다 . 이 경우 는 다른 객체입니다 . 속성을 , 로 설정합니다 . 즉, 관계는 상호적입니다. 즉, 당신은 친구의 친구입니다. 이 경우 Filou는 Ozzy의 친구가 되며, 즉 Ozzy는 자동으로 Filou의 친구가 됩니다. 메서드를 정의하는 대신 이러한 속성을 수동으로 설정할 수도 있지만, 친구를 설정할 때마다 더 많은 작업(한 줄 대신 두 줄의 코드를 작성)이 필요합니다. Python에서는 인수의 유형을 지정할 필요가 없습니다. 이것이 Java라면 필수입니다.
class Dog: def __init__(self, name, age): self.name = name self.age = age def bark(self): print(“bark bark!”) def doginfo(self): print(self.name + ” is ” + str(self.age) + ” year(s) old.”) def birthday(self): self.age +=1 def setBuddy(self, buddy): self.buddy = buddy buddy.buddy = self |
이제 점 표기법으로 메서드를 호출하고 다른 Dog객체를 전달할 수 있습니다. 이 경우 Ozzy의 친구는 Filou가 됩니다.
ozzy = Dog(“Ozzy”, 2) filou = Dog(“Filou”, 8) ozzy.setBuddy(filou) |
이제 오지의 친구에 대한 정보를 알고 싶다면 점 표기법을 두 번 사용할 수 있습니다. 첫 번째는 오지의 친구를 참조하고 두 번째는 해당 속성을 참조합니다.
print(ozzy.buddy.name) print(ozzy.buddy.age) Filou 8 |
이것이 Filou에게도 어떻게 가능한지 주목해보세요.
print(filou.buddy.name) print(filou.buddy.age) Ozzy 2 |
친구의 메서드도 호출할 수 있습니다. self전달되는 인수는 doginfo()now 이며 ozzy.buddy, 이는 filou.
ozzy.buddy.doginfo() Filou is 8 year(s) old. |
파이썬 OOP 예제
Python에서 객체 지향 프로그래밍이 유용할 수 있는 예로는 Python For Finance: Algorithmic Trading 튜토리얼이 있습니다. 여기에서 주식 포트폴리오에 대한 거래 전략을 설정하는 방법을 설명합니다. 거래 전략은 주가의 이동 평균을 기반으로 합니다. signals[‘short_mavg’][short_window:] > signals[‘long_mavg’][short_window:]충족되면 신호가 생성됩니다. 이 신호는 주식의 미래 가격 변화에 대한 예측입니다. 아래 코드에서 먼저 초기화가 있고 그 다음에 이동 평균 계산과 신호 생성이 있습니다. 이것은 객체 지향 코드가 아니므로 한 번에 실행되는 큰 청크 하나뿐입니다. 이 aapl예에서 사용하고 있는 것은 Apple의 주식 티커입니다. 다른 주식에 대해 이 작업을 수행하려면 코드를 다시 작성해야 합니다.
# Initialize short_window = 40 long_window = 100 signals = pd.DataFrame(index=aapl.index) signals[‘signal’] = 0.0 # Create short simple moving average over the short window signals[‘short_mavg’] = aapl[‘Close’].rolling(window=short_window, min_periods=1, center=False).mean() # Create long simple moving average over the long window signals[‘long_mavg’] = aapl[‘Close’].rolling(window=long_window, min_periods=1, center=False).mean() # Create signals signals[‘signal’][short_window:] = np.where(signals[‘short_mavg’][short_window:] > signals[‘long_mavg’][short_window:], 1.0, 0.0) # Generate trading orders signals[‘positions’] = signals[‘signal’].diff() # Print `signals` print(signals) |
객체 지향 방식에서는 초기화 및 신호 생성 코드를 한 번만 작성하면 됩니다. 그런 다음 전략을 계산하려는 각 주식에 대해 새 객체를 만들고 해당 객체를 호출할 수 있습니다 generate_signals(). OOP 코드는 위의 코드와 매우 유사하지만 self.
class MovingAverage(): def __init__(self, symbol, bars, short_window, long_window): self.symbol = symbol self.bars = bars self.short_window = short_window self.long_window = long_window def generate_signals(self): signals = pd.DataFrame(index=self.bars.index) signals[‘signal’] = 0.0 signals[‘short_mavg’] = bars[‘Close’].rolling(window=self.short_window, min_periods=1, center=False).mean() signals[‘long_mavg’] = bars[‘Close’].rolling(window=self.long_window, min_periods=1, center=False).mean() signals[‘signal’][self.short_window:] = np.where(signals[‘short_mavg’][self.short_window:] > signals[‘long_mavg’][self.short_window:], 1.0, 0.0) signals[‘positions’] = signals[‘signal’].diff() return signals |
이제 원하는 매개변수로 객체를 간단히 인스턴스화하고, 해당 객체에 대한 신호를 생성할 수 있습니다.
apple = MovingAverage(‘aapl’, aapl, 40, 100) print(apple.generate_signals()) |
다른 주식에 대해 이렇게 하는 것은 매우 쉽습니다. 다른 주식 기호로 새 객체를 인스턴스화하는 문제일 뿐입니다.
microsoft = MovingAverage(‘msft’, msft, 40, 100) print(microsoft.generate_signals()) |
파이썬에서의 객체 지향 프로그래밍: 마무리
Python에서 주요 OOP 개념 중 일부를 다루었습니다. 이제 클래스와 메서드를 선언하고, 객체를 인스턴스화하고, 속성을 설정하고, 인스턴스 메서드를 호출하는 방법을 알게 되었습니다. 이러한 기술은 데이터 과학자로서의 미래 경력에 유용할 것입니다.
OOP를 사용하면 프로그램이 커질수록 코드가 복잡해집니다. 다양한 클래스, 하위 클래스, 객체, 상속, 인스턴스 메서드 등이 있습니다. 코드를 적절하게 구조화하고 읽기 쉽게 유지해야 합니다. 그렇게 하려면 디자인 패턴을 따르는 것이 좋습니다. 이는 나쁜 디자인을 피하기 위한 일련의 지침을 나타내는 디자인 원칙입니다. 각각 Python OOP에서 자주 발생하는 특정 문제를 나타내며 해당 문제에 대한 솔루션을 설명하여 반복적으로 사용할 수 있습니다. 이러한 OOP 디자인 패턴은 생성 패턴, 구조적 패턴 및 동작 패턴의 여러 범주로 분류할 수 있습니다. 생성 패턴의 한 예는 싱글톤으로, 클래스의 인스턴스를 하나만 만들 수 있도록 하려는 경우 사용해야 합니다.