파이선 클래스 사용할때

qiiiiiiiip의 이미지


A 클래스에서 상속받은 , A-1, A-2, A-3 의 세개의 서브클래스가 있을때,

b = A( param )

라고 호출하면 param 에 따라서 A-1, A-2, A-3이 생성되어서 리턴하게 하려면
어떻게 하는것이 정석인가요??

b = createA( param ) 처럼 별도의 함수를 만드는것이 정석인가요?

cleansugar의 이미지

오버로딩 말씀하시는 건가요?

재벌 2세가 재벌이 될 확률과
금메달리스트 2세가 금메달을 딸 확률이 비슷해지도록
자유오픈소스 대안화폐를 씁시다.

아이디의 아이디어 무한도전
http://blog.aaidee.com

귀태닷컴
http://www.gwitae.com

qiiiiiiiip의 이미지

param의 type이 아니라, value에 따라서 달라지니까 오버로딩은 아니겠네요..

def createA( param ):
  if param == 1:
    return A-1()
  elif param == 2:
    return A-2()
  elif param == 3:
    return A-3()
  else:
    return A()

와 같은 식의 함수를 만드는게 일반적인 방법인지 궁금해서요..
아니면 A의 new를 새로 구현하는게 정석인지요..

snowall의 이미지

제 생각에는 정해진 정석은 없는 것 같고, 편한대로 하시면 될 것 같은데요.

그리고 제 생각에, 입력하는 타입이 같더라도 반환하는 타입이 달라지므로 오버로딩이 맞다고 봅니다.

더 정확히는, 생성자 오버로딩이 되겠죠.

피할 수 있을때 즐겨라! http://melotopia.net/b

qiiiiiiiip의 이미지

오버로딩이냐 아니냐는 오버로딩의 정의에 따라 다른거겠지요..
wikipedia의 정의에 따르면

The terms overloading and overloaded may refer to:
Constructor and function/method overloading, in computer science, a type of polymorphism 
where different functions with the same name are invoked based on the data types of the parameters passed

2가지 조건
1. different functions with the same name are invoked
2. based on the data types of the parameters

특히 1번조건을 만족하지 않으므로 오버로딩이 아니라고 보는 거고요....
1번조건을 만족하기 위해 컴파일러/인터프리터가 판단할 근거는 type(또는 # of params) 이겠지요.

결국 하고자 하는 목적이 비슷하므로 넓은 의미의 오버로딩이라고 볼 수도 있을테고..
어차피 파이선에서 오버로딩이라는 개념 자체가 무의미한 것이기도 하고요..

snowall의 이미지

네. 저도 뭔가 찝찝해서 더 알아봤더니 오버로딩의 정의에 들어가지는 않네요...

파이썬에서 오버로딩은 의미가 없긴 하죠.

그리고 더 생각해 보니까, 생성자 수준에서 정의하면 안되고, 그냥 입력값에 따라 다른 타입을 리턴해주는 함수를 정의하셔야 할 것 같습니다. 이건 파이썬이니까 쉽게 가능한 부분이 되겠네요.

피할 수 있을때 즐겨라! http://melotopia.net/b

sblade의 이미지

전형적인 factory pattern 인데
말하신대로 밖에다 함수를 만들거나
아니면 함수 자체의 scope 가 A 안에 있는 걸 선호하면 (즉 A.createA() 처럼 호출할 수 있게)
@staticmethod 나 @classmethod 로 A 안에다 createA method 를 만들면 됩니다.
createA 의 인자를 좀 자유롭게 설정하고 싶으면 **kwargs 를 사용하세요

class A(object):
    @staticmethod
    def createA(**kwargs):
        if ...:
            return A1(...)
        elif ...:
            return A2(...)

대강 이런 식으로들 씁니다.

익명 사용자의 이미지

저도 이 패턴 만날 때마다 뭔가 다른 방법 없을까 고민하면서 __new__ 오버라이딩도 해보고 meta class도 써보고 이리저리 해봤습니다만..

그냥 함수 하나 속에서 if .. elif .. elif 로 시작하는게 제일 명료하고 유연하다는 잠정 결론을 내리고 있습니다. 예로 드신 것 대로라면 createA()겠네요. 물론 이걸 A의 classmethod나 staticmethod로 해서 A.create(param) 같은 식으로 해도 무방하지만 전 그냥 free function으로..

일단 여기서 출발해서, 필요에 따라 decorator를 이용한다거나 하는 식으로 변형하고 있습니다. 왠만해선 이 이상 필요 없더군요.

__new__나 meta class를 쓰면 근사하긴 하지만, 왠만큼 코드 스케일이 커지지 않는 한 배보다 배꼽이 크다는 생각입니다. 적어도 createA() 대신 A()라고 할 수 있는 정도의 장점을 얻자고 들일 노력은 아니다 싶더군요.

익명 사용자의 이미지

덧붙여서 __new__는 __init__과 인자가 연동되는 부분이 있어서, A-1/A-2/A-3에 들어가는 param들이 정형화되지 않거나, __init__이 있거나 없거나 달라지거나 하면 꽤 걸리적거리기도 하더군요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.