2012-06-07 3 views
3

C++ 클래스를 래핑 할 때 __cinit__ 메서드를 cython에서 오버로드 할 수 없다는 문제를 해결할 표준화 된 (또는 일반적으로 받아 들인 방식)가 있습니까?Cython 및 오버로드 된 C++ 생성자

__cinit__은 매개 변수를 포함하기 위해 * args 및 ** kwargs를 취할 수 있으며 __cinit__ 범위에는 특정 패턴에 따라 C++ 인스턴스를 생성하는 방법을 선택합니다. 인수의 이름 및 사용자를위한 성가신 될 수도 kwargs로로 전달되지 않는 특정 상황에서 위험 할 수있는 인수에서 올바른 생성자를 식별하기 위해 노력

  • :이 방법은 그러나 합병증이있다.
  • 인수가 __cinit__ 인수 목록의 해당 형식으로 호출되지 않으면 해당 인수는 Python 개체로 전달됩니다. 제 작업 예제에서 인수는 C++ 클래스의 파이썬 래퍼입니다.이 인스턴스를 검색하려고하면 "thisptr"은 * args 또는 ** kwargs에서 파이썬 객체로 전달 될 때 악마의 작업입니다.
  • 인수 조합에서 C++ 생성자를 선택하기 위해 if ... elif ... else 경우의 시퀀스를 사용하려면 암시 ​​적으로 상당히 혼란스러워해야합니다.

그래서 더 좋은 방법이 있어야합니다. 한 가지 방법으로 클래스 방법을 사용할 수 있습니다 (예 : classmethod to overload __init__ behavior in Python 참조). 그럼에도 불구하고, 내가 아는 한 (그리고 내가 틀렸다고 정정 해주십시오) classmethod는 클래스 이름이 다른 메소드를 호출하는 것을 의미합니다. 이것은 하나의 클래스 이름으로 인스턴스를 생성하는 C++ 방식과 잘 맞지 않습니다.

이것에 대한 아이디어가 있습니까?

답변

2

개인적으로 나는 classmethods를 사용합니다.

WrapperClass.fromSpambar(spambar) 

그것은 그 puzzlin 이럴 아니다. C++에서 함수를 오버로드 할 수 없다면이 접근 방식으로 대체해야합니다.

초기 설정에서 무거운 가중치 연산을 허용 할 수있는 경우 "패턴"또는 이와 유사한 정의를 통해 생성자가 호출 된 방식을 인식하는 메소드를 구현할 수 있습니다. 나는. args 및 kwargs에 대한 정규 표현식. ;)

thisptr을 얻는 데 문제가 보이지 않습니다.을 Python 개체에서 가져옵니다.

cdef WrapperClass wrpclsi 
if isinstance(instance, WrapperClass): 
    wrpclsi = instance 
else: 
    raise TypeError('expected instance of WrapperClass.') 

cdef WrappedClassFromCpp* thisptr = wrpclsi.thisptr 
+0

감사합니다. Niklas, 예,이 방법은 classmethods를 사용하며, 특정 인수 유형 조합에 대한 처리를 더욱 안전하게 만듭니다. Regex는 아마도 클래스 메소드와 함께 유용 할 것입니다 (예를 들어, 인수 유형의 조합이 주어진 특정 classmethod 생성자를 선택하는 것이 의미가있는 경우). –

+0

thisptr 부분에 관해서 ... 그렇습니다. 나는이 지점에서 제가 말하고자하는 것에 대해 명확한 설명이 필요하다고 생각합니다. 제 요점은 'def __cinit __ (self, PyKlass klass)' 과 같은 것을 선언하는 것이 었습니다.'__cinit__ '범위 안에'klass.thisptr'을 호출하는 데 문제가 없습니다. 그러나 args [0]에 PyKlass 인스턴스가 있다고 가정하고 args [0]이 호출 되더라도 args [0] .thisptr를 호출하면 문제가 발생합니다. PyClass 유형의 인스턴스 '의 klass = 인수 [0]' –

+0

안녕하세요 tachys : 그것은 그 큰 문제가 아니라 단순히 같은 __cinit__''내에서 주조에 의해 해결할 수 있습니다 밝혀졌습니다. 나는 실제 정규 표현식에 대해 실제로 말하지 않았다. 단지 비슷한 메커니즘으로 작동하지만 args *와 * kwargs *와 일치하는 것일 뿐이다. 함수가 전달 된 인수를 받아 들인 인수에 매핑하는 것과 같은 방식으로 * args * 및 * kwargs *를 처리 할 수 ​​있지만 여러 호출 규칙을 허용합니다. 그러나, 이것은 대규모로 느려질 수있는 처리를 수반 할 것입니다. 다음 날에 몇 가지 예제 코드를 작성할 수 있습니다. –

관련 문제