[python] 파이썬에서 언제 클래스를 사용해야합니까?

저는 약 2 년 동안 파이썬으로 프로그래밍 해 왔습니다. 주로 데이터 (팬더, mpl, numpy)뿐만 아니라 자동화 스크립트 및 소규모 웹 앱도 있습니다. 나는 더 나은 프로그래머가되고 파이썬 지식과 나를 귀찮게하는 것 중 하나를 배우려고 노력하고있다. 나는 일반적으로 그들이 무엇인지 이해하지만 간단한 기능을 통해 왜 그것들을 필요로하는지 머리를 감쌀 수는 없습니다.

내 질문에 특이성을 더하기 위해 : 나는 항상 여러 데이터 소스 (mongo, sql, postgres, apis)에서 데이터를 가져 오거나 많은 데이터 소거 및 서식을 수행하고 csv / excel에 데이터를 쓰는 수많은 자동화 된 보고서를 작성합니다. / html, 이메일로 보내십시오. 스크립트 범위는 ~ 250 줄 ~ ~ 600 줄입니다. 클래스를 사용하여이를 수행하는 이유와 이유가 있습니까?



답변

클래스는 객체 지향 프로그래밍 의 기둥입니다 . OOP는 코드 구성, 재사용 성 및 캡슐화에 크게 관심이 있습니다.

첫째, 면책 조항 : OOP는 부분적으로 파이썬에서 많이 사용되는 다른 패러다임 인 Functional Programming 과 대조됩니다 . 파이썬 (또는 대부분의 언어)으로 프로그래밍하는 모든 사람이 OOP를 사용하는 것은 아닙니다. Java 8에서는 객체 지향적이지 않은 많은 작업을 수행 할 수 있습니다. OOP를 사용하지 않으려면 사용하지 마십시오. 다시는 사용하지 않을 데이터를 처리하기 위해 일회용 스크립트를 작성하는 경우에는 그대로 사용하십시오.

그러나 OOP를 사용해야하는 많은 이유가 있습니다.

몇 가지 이유 :

  • 조직 : OOP는 코드에서 데이터와 프로 시저를 모두 설명하고 정의하는 잘 알려진 표준 방법을 정의합니다. 데이터와 프로시 저는 다양한 수준의 정의 (다른 클래스로)로 저장 될 수 있으며 이러한 정의에 대해 이야기하는 표준 방법이 있습니다. 즉, 표준 방식으로 OOP를 사용하면 나중에 자신과 다른 사람이 코드를 이해하고 편집하고 사용하는 데 도움이됩니다. 또한 복잡한 임의의 데이터 저장 메커니즘 (dicts 또는 list 또는 dicts 또는 set of dicts 등의 목록 등)을 사용하는 대신 데이터 구조의 이름을 지정하고 편리하게 참조 할 수 있습니다.

  • 상태 : OOP는 상태를 정의하고 추적하는 데 도움이됩니다. 예를 들어, 전형적인 예에서 학생을 처리하는 프로그램 (예 : 학년 프로그램)을 작성하는 경우 필요한 모든 정보를 이름, 나이, 성별, 학년, 코스, 성적, 교사, 동료,식이 요법, 특별 요구 사항 등),이 데이터는 개체가 살아있는 한 지속되며 쉽게 액세스 할 수 있습니다.

  • 캡슐화 : 캡슐화를 통해 프로 시저와 데이터가 함께 저장됩니다. 방법 (함수에 대한 OOP 용어)은 작동하고 생성하는 데이터와 함께 정의됩니다. 액세스 제어 를 허용하는 Java와 같은 언어 또는 Python에서는 공용 API를 설명하는 방법에 따라 메소드와 데이터를 사용자에게 숨길 수 있습니다. 이것이 의미하는 바는 코드를 필요로하거나 변경하려는 경우 코드 구현에 원하는 모든 작업을 수행 할 수 있지만 공개 API는 동일하게 유지한다는 것입니다.

  • 상속 : 상속을 사용하면 한 곳에서 (한 클래스에서) 데이터와 프로 시저를 정의한 다음 나중에 해당 기능을 재정의하거나 확장 할 수 있습니다. 예를 들어, 파이썬에서는 dict추가 기능을 추가하기 위해 클래스의 하위 클래스를 만드는 사람들이 종종 있습니다 . 일반적인 변경은 알 수없는 키를 기반으로 기본값을 제공하기 위해 존재하지 않는 사전에서 키를 요청할 때 예외를 발생시키는 메소드를 대체하는 것입니다. 이를 통해 지금 또는 나중에 자신의 코드를 확장하고, 다른 사람들이 귀하의 코드를 확장하고, 다른 사람들의 코드를 확장 할 수 있습니다.

  • 재사용 성 : 이러한 모든 이유 및 기타 이유로 인해 코드의 재사용 성이 향상됩니다. 객체 지향 코드를 사용하면 견고한 (테스트 된) 코드를 한 번 작성한 다음 반복해서 재사용 할 수 있습니다. 특정 사용 사례에 맞게 무언가를 조정해야하는 경우 기존 클래스에서 상속하고 기존 동작을 덮어 쓸 수 있습니다. 무언가를 변경해야 할 경우 기존의 공개 메소드 서명을 유지하면서 모든 것을 변경할 수 있으며 아무도 현명하지 않습니다.

다시 말하지만 OOP를 사용하지 않는 몇 가지 이유가 있으며 필요하지 않습니다. 그러나 운 좋게 파이썬과 같은 언어를 사용하면 약간 또는 많이 사용할 수 있습니다.

학생 유스 케이스의 예 (코드 품질에 대한 보장은 아니며 단지 예) :

객체 지향

class Student(object):
    def __init__(self, name, age, gender, level, grades=None):
        self.name = name
        self.age = age
        self.gender = gender
        self.level = level
        self.grades = grades or {}

    def setGrade(self, course, grade):
        self.grades[course] = grade

    def getGrade(self, course):
        return self.grades[course]

    def getGPA(self):
        return sum(self.grades.values())/len(self.grades)

# Define some students
john = Student("John", 12, "male", 6, {"math":3.3})
jane = Student("Jane", 12, "female", 6, {"math":3.5})

# Now we can get to the grades easily
print(john.getGPA())
print(jane.getGPA())

표준 딕트

def calculateGPA(gradeDict):
    return sum(gradeDict.values())/len(gradeDict)

students = {}
# We can set the keys to variables so we might minimize typos
name, age, gender, level, grades = "name", "age", "gender", "level", "grades"
john, jane = "john", "jane"
math = "math"
students[john] = {}
students[john][age] = 12
students[john][gender] = "male"
students[john][level] = 6
students[john][grades] = {math:3.3}

students[jane] = {}
students[jane][age] = 12
students[jane][gender] = "female"
students[jane][level] = 6
students[jane][grades] = {math:3.5}

# At this point, we need to remember who the students are and where the grades are stored. Not a huge deal, but avoided by OOP.
print(calculateGPA(students[john][grades]))
print(calculateGPA(students[jane][grades]))


답변

함수의 상태를 유지해야 할 때마다 생성기 (복귀하지 않고 생성되는 함수)로는 수행 할 수 없습니다. 발전기는 자체 상태를 유지합니다.

표준 연산자 를 재정의 하려면 클래스가 필요합니다.

방문자 패턴을 사용할 때마다 수업이 필요합니다. 다른 모든 디자인 패턴은 생성기, 컨텍스트 관리자 (클래스보다 생성기로 더 잘 구현 됨) 및 POD 유형 (사전, 목록 및 튜플 등)을 사용하여보다 효과적이고 깨끗하게 달성 할 수 있습니다.

“pythonic”코드를 작성하려면 클래스보다 컨텍스트 관리자 및 생성기를 선호해야합니다. 깨끗합니다.

기능을 확장하려는 경우 거의 항상 상속이 아닌 격리로 기능을 수행 할 수 있습니다.

모든 규칙에 따라 예외가 있습니다. 기능을 빠르게 캡슐화하려면 (즉, 라이브러리 수준 재사용 가능 코드 대신 테스트 코드 작성) 상태를 클래스에 캡슐화 할 수 있습니다. 간단하고 재사용 할 필요가 없습니다.

C ++ 스타일 소멸자 (RIIA)가 필요한 경우 클래스를 사용하고 싶지 않습니다. 컨텍스트 관리자가 필요합니다.


답변

나는 당신이 그것을 올바르게 생각합니다. 어려운 비즈니스 관계 또는 어려운 실제 프로세스를 시뮬레이션해야하는 경우 클래스는 합리적입니다. 예를 들어 :

  • 공유 상태를 가진 여러 기능
  • 동일한 상태 변수의 둘 이상의 사본
  • 기존 기능의 동작을 확장하려면

또한 이 클래식 비디오 를 시청할 것을 제안합니다


답변

클래스는 실제 개체를 정의합니다. 개별적으로 존재하고 다른 논리와 분리 된 자체 논리가있는 작업을 수행하는 경우이를위한 클래스를 작성해야합니다. 예를 들어 데이터베이스 연결을 캡슐화하는 클래스입니다.

그렇지 않은 경우 클래스를 만들 필요가 없습니다.


답변

그것은 당신의 아이디어와 디자인에 달려 있습니다. OOP보다 훌륭한 디자이너라면 다양한 디자인 패턴의 형태로 자연스럽게 나옵니다. 간단한 스크립트 수준 처리를 위해 OOP가 오버 헤드가 될 수 있습니다. 재사용 및 확장과 같은 OOP의 기본 이점을 간단히 고려하여 필요한지 여부를 확인하십시오. OOP는 복잡한 것을 단순하고 단순하게 만듭니다. OOP를 사용하거나 OOP를 사용하지 않는 방식으로 간단하게 유지하십시오. 어느 것이 더 사용하기 쉽습니다.


답변