class 클래스이름:
   def 메소드(self, param1, param2, ...):
        pass
첫번째 인자에 항상 객체 자신을 의미하는 self 파라미터를 가짐
해당 메서드를 호출한 객체에만 영향을 미침
호출 방법
self.메소드명객체.메소드명예시
class ClassTest:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def print_info(self):
        print(self.name, self.age)
    
    def test_func(self):
        self.print_info()   #클래스 안에서는 self.메서드명
test = ClassTest('Kim', 10)
test.print_info()  #클래스 밖에서는 객체.메서드명
test.test_func()
#출력 결과
#Kim 10
#Kim 10
class 클래스이름:
   @classmethod
   def 메소드(cls, param1, param2, ...):
        pass
self 파라미터 대신 cls라는 클래스를 의미하는 파라미터 가짐
클래스 메소드를 지정하기 위해 @classmethod 사용
객체의 속성/메서드에는 접근 불가
(cls.클래스속성명으로 클래스 속성에는 접근 가능)
cls를 사용하면 클래스 메서드 내부에서 현재 클래스의 인스턴스를 만들 수 있음 
클래스명.클래스메서드명, 객체명.클래스메서드명으로 호출 가능
예시1
class Person:
    count = 0
    def __init__(self):
        Person.count += 1
    
    @classmethod
    def print_count(cls):
        print(f'{cls.count}명 생성되었습니다')  #클래스 속성 접근 가능
    
    @classmethod
    def create(cls):
        p = cls()   #메서드 내부에서 cls()로 현재 클래스의 인스턴스 만들 수 있음
        return p
human1 = Person()
human2 = Person()
Person.print_count()
print(Person.create())
#출력 결과
#2명 생성되었습니다
#<__main__.Person object at 0x00C68238>
예시2
class User:
    def __init__(self, email, password):
        self.email = email
        self.password = password
    
    @classmethod
    def fromTuple(cls, tup):
        return cls(tup[0], tup[1])
    
    @classmethod
    def fromDictionary(cls, dic):
        return cls(dic['email'], dic['password'])
#기본 생성자로 객체 생성
user = User("user@test.com", "1234")
print(user.email, user.password)
#클래스 메소드로 튜플로부터 객체 생성
user = User.fromTuple(("user@test.com", "1234"))
print(user.email, user.password)
#클래스 메소드로 딕셔너리로부터 객체 생성
user = User.fromDictionary({"email": "user@test.com", "password": "1234"})
print(user.email, user.password)
#출력 결과
#user@test.com 1234
#user@test.com 1234
#user@test.com 1234
class 클래스이름:
   @staticmethod
   def 메소드(param1, param2, ...):
        pass
스태틱 메소드를 지정하기 위해 @staticmethod 사용
인스턴스를 만들지 않아도 클래스.메소드()로 바로 호출 가능
self를 받지 않아서 인스턴스 속성에는 접근 불가
(정적 메소드 내부에서 클래스 변수에는 클래스.클래스속성명으로 접근 가능)
self를 받지 않아서 인스턴스/클래스 메서드 호출 불가
인스턴스 속성, 인스턴스 메소드가 필요 없을 때 사용
인스턴스의 상태를 변화시키지 않는 메소드를 만들 때 사용
예시1
class Calc:
    count = 10  #클래스 변수
    @staticmethod
    def add(a):
        print(a + Calc.count)	#클래스 속성에는 접근 가능
    
    @staticmethod
    def mul(a):
        print(a * Calc.count)
Calc.add(10)	#클래스에서 바로 메소드 호출
Calc.mul(10)	#클래스에서 바로 메소드 호출
#출력 결과
#20
#100
예시2
class StringUtils:
    @staticmethod
    def toCamelCase(text):
        words = iter(text.split('_'))
        return next(words) + "".join(i.title() for i in words)
    
    @staticmethod
    def toSnakecase(text):
        letters = ["_" + i.lower() if i.isupper() else i for i in text]
        return "".join(letters).lstrip("_")
print(StringUtils.toCamelCase('last_modifed_date'))
print(StringUtils.toSnakecase('lastModifiedDate'))
#출력 결과
#lastModifedDate
#last_modified_date
. 오퍼레이터를 붙여서 호출 가능cls 인자를 활용하여 현재 클래스 속성을 가져오고class Test:
    default = "parent"
    def __init__(self):
        self.data = self.default
    
    @classmethod
    def class_test(cls):
        return cls()
    
    @staticmethod
    def static_test():
        return Test()
    
class ChildTest(Test):
    default = "child"
test1 = ChildTest.class_test()
test2 = ChildTest.static_test()
print(test1.default)
print(test2.default)
#출력 결과
#child
#parent
침고
https://journeytosth.tistory.com/73
https://kwonkyo.tistory.com/243
https://dojang.io/mod/page/view.php?id=2379
https://www.daleseo.com/python-class-methods-vs-static-methods/
https://hckcksrl.medium.com/python-%EC%A0%95%EC%A0%81%EB%A9%94%EC%86%8C%EB%93%9C-staticmethod-%EC%99%80-classmethod-6721b0977372
https://nirsa.tistory.com/113