마법사님의 트윗으로 부터 인사이트 출판사의 전자책 서비스 종료 소식을 접했다.  먼저 13년 동안 묵묵히 운영해 온 인사이트에게 독자의 한사람으로서 감사의 마음을 표한다. 인사이트 전자책 서비스는 단순한 전자책 판매 서비스가 아니라 국내 IT 출판 업계의 가장 진보적이고 실험적인 시도였다고 생각한다.

 

 

 

출판사 블로그를 되돌아 보니 2012년 4월 18일 PDF로 전자책 서비스를 시작했다.  Mobi도 아니고 ePub도 아닌 PDF파일을, 그것도 수작업 결제 처리로 전자책 서비스를 시작한다는 것은 당시로서는 상상하기 어려운 모험이었을 것이다.(만약 내가 사업 담당자라면 이 서비스를 기획한 사람을 싫어했을 것이다.) 더욱 놀라운 것은 서비스 철학이었다. 암호도 없고, DRM도 없이 그냥 자유롭게 자신이 좋아하는 뷰어로 볼 수 있도록 PDF 파일을 보내주는 방식. 기술적으로는 단순하지만 사업적으로는 위험한 선택이었음이 분명하다. 하지만 이 점이 인사이트 전자책 서비스의 정체성을 제대로 드러낸다고 생각한다.

 

 

인사이트가 PDF 서비스를 시작합니다.

전자책이 책 세상을 뒤덮을 것 같은 시대에도 꿋꿋이 종이책만 내던 인사이트에서, 드디어 작은 발걸음을 내딛어 봅니다. 바로 PDF 서비스입니다. 아직 시작 단계라서 PDF 뿐이고, 결제도 수동식

blog.insightbook.co.kr

 

13년간 이 서비스가 지속될 수 있었던 것은 기술력이라기 보다는 철학 때문이리라. 한기성 사장님께 불법적인 PDF 유통이나 허락되지 않은 AI 학습에의 활용이 걱정되지 않느냐고 여쭤본 적이 있었다.  "허허.. 그 분들은 우리 책의 독자가 원래 안될 분이지 않을까요? 오히려 우리 독자분들에게 불편함을 드릴 수는 없지 않나요?"라는 사장님의 말씀에 이 서비스의 본질이 들어있다. 독자와의 신뢰 관계. 고객 중심에서 생각하는 서비스... 단순히 책이라는 상품을 만들어 사고 파는 것이 아니다.

 

개인적으로 미국에서 개발자 생활을 했었는데, 인사이트의 DRM-Free PDF는 정말 소중한 존재였다. 언어의 장벽없이 고급 콘텐츠를 누리고 싶은데, 교보나 예스 24같은 전자책 플랫폼은 당시 해외에서 사용하기에 여러 제약이 있었다. 본인 인증부터 시작해서 느린 인터넷 환경때문에 DRM인증 자체가 실패하거나 국가 제한에 걸려 보지못하는 경우도 있었다. 그런 상황에서 인사이트의 PDF는 단순히 파일을 다운로드 받아 자유롭게 책을 읽을 수 있는 기쁨을 제공했다. 아이패드든 킨들이든 노트북이든 상관없이 말이다. (하지만 나는 인사이트의 종이책을 너무 사랑해서 한국에 들릴 때마다 잔뜩 사들고 갔다. 한국과 미국을 거쳐 다시 돌아온 나의 책들...)

 

아쉽게도 인사이트의 Free DRM 실험은 IT 출판 업계 전반으로 확산되지 못했다. 다른 출판사들이 이렇게 못한 이유는 분명하다. 위험 부담이 너무 크고, 수익성에 대한 확신이 없기 때문이다. 특히 최근 인공지능의 확산 속에 허락받지 않은 학습에의 오용도 한 몫했으리라. 하지만 오라일리의 SafariBooks처럼 출판사들이 협력하는 플랫폼이 국내에서도 더 활성화되었으면 좋겠다. 기술적으로는 지금도 충분히 구현가능하지만, 업계의 의지와 독자의 인식 변화가 필요한 부분이다. (아직 AI 학습에 활용하는 문제는 역저자와 출판사, 출판사와 출판사의 권리 관계가 명확히 정리되지 않았다.)

 

비 오는 저녁, 한 시대의 마감을 지켜보며 드는 생각이다. 우리나라가 K-IT Contents 강국이 되는 날이 올 수 있을까 하는 막연한 생각을 해본다.

 

반응형

 

이번에 나눌 이야기는 파이썬 클래스에서 동적으로 메서드를 생성하는 방법에 대한 이야기입니다. dataclass 데코레이터의 동작 원리를 살펴보다가 알게된 내용을 정리해 봅니다.

 

EXEC 함수 

먼저 exec 함수에 대해 알아봅니다.

이 함수는 텍스트로 작성된 코드를 실행하기 위한 용도로 사용됩니다. 즉, 파이썬 코드 문자열을 동적으로 실행하는 기능을 제공합니다.

exec('print("Hello World")')

 

이 코드를 실행하면 마치 파이썬 코드로 print("Hello World")를 실행한 것과 동일한 결과를 얻습니다. 여기까지는 많이들 보셨을 텐데요, exec 함수의 서명(signature)는 다음과 같습니다.

exec(object[, globals[, locals]])

 

두번째 인자와 세번째 인자는 스코프의 네임스페이스입니다.  따라서 특정 인수값을 전달하지 않으면 현재의 전역/지역 네임스페이스를 기반으로 실행됩니다.

exec(object) # 현재 스코프에서 코드 실행
exec(object, globals) # 주어진 전역 네임스페이스에서 실행
exec(object, globals, locals) # 전역과 지역 네임스페이스를 분리하여 실행

 

 

SETATTR 함수

setattr 함수는 객체의 속성을 동적으로 추가하거나 변경하는 함수입니다. 즉, 클래스/객체에 속성을 추가하거나 기존 속성을 수정할 수 있습니다. 이 함수의 서명은 다음과 같습니다.

setattr(object, name, value)
# object: 속성을 추가하거나 수정할 대상 객체
# name: 속성의 이름(문자열)
# value: 설정할 속성 값

 

예를 들어 빈 Person이라는 클래스를 만들고, 여기에 name이라는 속성을 동적으로 추가해 봅시다.

class Person:
    pass  # 빈 클래스 정의

p = Person()

# 동적으로 'name' 속성 추가
setattr(p, 'name', 'neozest')
print(p.name)  # neozest

 

 

클래스에 메서드 동적으로 추가하기

파이썬에서 함수는 1급 시민입니다. 즉, 함수 자체를 인수로 주고 받을 수도 있습니다.

이번에는 Animal 클래스를 만들고, 여기에 speak 메서드를 동적으로 추가해 보겠습니다. 먼저 클래스 코드!

 

class Animal:
    def __init__(self, name):
        self.name = name

a = Animal("Dog")
a.speak()  # AttributeError 발생!

 

AttributeError 예외가 발생했습니다. 당연한 결과죠. Animal 클래스에 speak 메서드가 정의되어 있지 않습니다. 

 

이번엔 동적으로 메서드를 추가해 보겠습니다. 본질적으로 어떤 함수 정의 객체를 클래스에 추가하는 작업입니다. 이를 보다 추상화해서 특정 클래스에 특정 코드를 메서드로 추가하는 함수를 만들어 봅니다.

def add_method(cls, method_name, method_body):
    code = f"def {method_name}(self): {method_body}"
    exec(code, globals(), locals())
    setattr(cls, method_name, locals()[method_name])

 

code는 함수를 선언하기 위해 만든 문자열입니다. 이 함수 정의 코드 문자열을 exec 함수를 사용하여 전역/지역 네임스페이스에서 실행합니다. 그렇게 만들어진 속성(메서드)를 setattr함수를 사용하여 특정 클래스의 신규 속성으로 등록합니다.

이제 Animal 클래스에 새로운 메서드를 추가한 후 speak 메서드를 호출해 봅니다.

add_method(Animal, "speak", 'print(f"{self.name} makes a sound")')

a = Animal("Dog")
a.speak()  # Dog makes a sound

 

이제 문제없이 speak 메서드를 호출할 수 있습니다.

 

심지어 람다함수로도 메서드를 동적으로 추가할 수 있습니다.

setattr(Animal, "shout", lambda self: "Roar!")

print(a.shout())  # Roar!

 

 

마무리 - dataclass 데코레이터

dataclass 데코레이터는 클래스 정의를 자동화하는 기능을 제공하여 __init__, __repr__, __eq__와 같은 던더 메서드를 직접 작성하지 않아도 자동으로 생성해 줍니다. dataclass 데코레이터는  클래스의 __annotations__ 던더 속성을 이용하여 사용자 정의 클래스를 수정합니다. 이 속성은 클래스에 대한 메타정보,즉  변수, 속성, 함수 인자, 반환값 등에 대한 타입 힌트를 담고 있습니다. 이 속성을 이용하여 필요한 메서드를 동적으로 클래스에 추가할 수 있습니다.

 

알아두면 좋을법한 관련 정보

데코레이터, 네임스페이스에 대한 보다 자세한 이야기는 제가 번역하고 인사이트 출판사에서 펴낸 <Python How-To: 파이썬다운 코드를 개발하는 63가지 실용기법>의 다음 부분에 설명되어 있습니다.

  • dataclass 데코레이터:Python How-to의 9.2절에 자세히 설명되어 있습니다.
  • LEGB 네임스페이스 규칙: Python How-to의 10.3절에 자세히 설명되어 있습니다.
  • 데코레이터: Python How-To의 7.3절에 자세히 설명되어 있습니다.

책을 구매하시면 출판사에서 더 좋은 파이썬 책을 만드는데 도움이 되지 않을까요. :)

 

알라딘: https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=369848931

교보: https://product.kyobobook.co.kr/detail/S000217294649

YES24: https://www.yes24.com/product/goods/151253343

 

 

파이썬다운 코드를 개발하는 63가지 실용 기법 | 프로그래밍 인사이트 Programming Insight | 용 추이

63가지 핵심 파이썬 기술을 익힐 수 있는 간단하지만 강력한 방법을 제시한다. 예를 들어, ‘시퀀스에서 항목을 찾으려면 어떻게 해야 할까?’와 같은 질문에서 출발하여 매우 명확한 기본 해결

www.aladin.co.kr

 

 

반응형

+ Recent posts