2016-06-03 6 views
2

__str__()의 출력을 변경하고 싶습니다. **kwargs을 추가하고 싶습니다.개체의 __str __()의 서명에 ** kwargs를 추가하는 방법은 무엇입니까?

문제점 : 함수의 서명을 변경할 수없는 것처럼 보입니다. 예를 들어

:

#!/usr/bin/env python3 

class my_printable_obj(object): 

    def __init__(self, s): 
     self.content = s 

    def __str__(self, **kwargs): 
     fancy = kwargs.get('fancy', '') 
     return str(self.content) + fancy 



M = my_printable_obj("Something to print") 

print(str(M)) 
print(str(M, fancy=' + a fancy part')) 

출력은 :

$ ./test_script3str.py 
Something to print 
Traceback (most recent call last): 
    File "./test_script3str.py", line 17, in <module> 
    print(str(M, fancy=' + a fancy part')) 
TypeError: 'fancy' is an invalid keyword argument for this function 

나는 형식 오류 메시지에도 불구하고, 파이썬 (쉽게 관찰 __str__()의 시작에 print('here')를 추가 할 수 있습니다) my_printable_obj.__str__()를 사용 않았다 것을 알 수 있습니다.

해결 방법이 있습니까? 아니면 어떤 이유로 든 가능하지 않습니까? into_str(self, **kwargs)과 같은 다른 함수를 정의하고 __str__() 대신 M.into_str(fancy=' something more')을 사용해야합니까?

주 :이 글을 쓰는 :

def __str__(self, fancy=''): 
    return str(self.content) + fancy 

정확히 같은 오류를 제공합니다.

+3

'str()'의 표준 구현이 아니라'.__ str __()'구현에'** kwargs'를 추가 할 수 있습니다. '.fancyStr()'와 같이 더 넓은 인터페이스를 가진 별도의 메소드를 사용하는 것을 고려하십시오; '.__ str __()'을 호출 할 수도 있습니다. – 9000

+0

네,하지만'str ​​(M, fancy = '+ fancy part')'같은 것을 사용할 수 있습니까? 말하자면'str (M) '을 호출 할 수는 있지만'kwarg'를 사용하기 위해서는 M.fancyStr (fancy ='... ')를 직접 사용해야합니다. – zezollo

+0

개체의 속성을 기반으로 별도의 문자열을 렌더링하려는 경우 별도의 메서드를 사용합니다. 객체의 속성에 대해 신경 쓰지 않는다면 객체 문자열 밖에서 수행 할 것입니다. 아마도 장식 자 패턴을 사용하여, 아마도 일반 문자열 연결만으로도 가능할 것입니다.왜 모든 사람들이 당신의 구체적인 예에서'str()'을 기대하는 바를 바꾸고 싶은지 모르겠다. – chelmertz

답변

2

내장 str있는 type이다. str(custom_object)과 같은 것을 실행하면 str의 생성자는 객체의 __str__() 메서드를 호출합니다. 덮어 쓰지 않고 유형의 서명을 변경할 수는 없습니다 (실제로 좋은 생각은 아닙니다).

class Example: 
    def __str__(self, **kwargs): 
     return 'kwargs: {}'.format(kwargs) 

print str(Example(), arg1=1, arg2=2) 
# kwargs: {'arg1': 1, 'arg2': 2} 

아마 명시 적으로 "가되는에도 불구하고, 사용자 정의 개체의 __str__ 메소드를 호출하기 위해 더 좋은 생각이 될 것입니다 :

class _str(str): 
    def __new__(cls, *args, **kwargs): 
     if args: 
      obj = args[0] 
      if hasattr(obj, '__str__'): 
       return obj.__str__(**kwargs) 
     return str.__new__(cls, *args, **kwargs) 
str = _str 

그래, 분명히 좋은 생각하지만, 여기에는 사용의 dunder "방법.

+0

좋아, 나는'__str __()'과 _builtin_'str()'사이에 혼란스러워했다. 나는 분명히'str()'을 덮어 쓰고 싶지 않다. 내가 원했던 것을하기 위해 필요한 것이다. 그래서 나는하지 않겠지 만, 사실에도 불구하고 어떻게 잘못된 생각인지를 보여 주신 것에 대해 감사드립니다. – zezollo

5

kwarg를 사용하여 호출하는 함수는 str (the inbuilt function)입니다.

str() 귀하의 개체에 __str__ 메서드를 호출합니다.


은 아마 당신이 찾고있는 무슨 __format__

>>> class MyPrintableObj(object): 

    def __init__(self, s): 
     self.content = s 

    def __format__(self, formatstr): 
     return str(self.content) + formatstr 

>>> m = MyPrintableObj("Something to print") 
>>> '{: a fancy string}'.format(m) 
'Something to print a fancy string' 
+0

두 가지 대답 중 하나를 선택하기가 쉽지 않습니다. 하지만 +1이기 때문에 흥미 롭습니다. (케이스를 해결하는 또 다른 방법은, 내가하고 싶은 일이 정확히 아니지만 가능하지만 좋은 아이디어는 아닙니다.) – zezollo