Python의 목록 개체에서 __str__ 메소드를 교체하십시오

StackOverflow https://stackoverflow.com/questions/931699

  •  06-09-2019
  •  | 
  •  

문제

이것은 간단한 것 같습니다.

나는 원한다 list 다른 것과 마찬가지로 list, 그것은 다른 것을 제외하고 .__str__ 방법.

  1. 설정하려고합니다 object.__str__ = foo 읽기 전용 오류가 발생합니다
  2. 서브 클래스를 시도합니다 list 기존을 변환하는 방법이 필요하다는 것을 의미합니다 list 서브 클래스의 인스턴스로. 이를 위해서는 모든 속성을 수동으로 복사하거나 (큰 통증), 어떻게 든 자동으로 복사해야합니다.
  3. 주위에 래퍼를 쓰려고합니다 list 개체 .__str__ 내 자신의 방법으로 처리합니다. 이 작업을 수행하는 방법을 모릅니다.

모든 대안 또는 솔루션 #2 또는 #3에게 큰 감사를 표합니다. 감사!

도움이 되었습니까?

해결책

이 솔루션은 래퍼없이 작동합니다. ADD로 두 목록에 가입하면 작동합니다. 목록 자체를 수정하는 모든 작업은 예상대로 작동합니다. 다음과 같은 목록의 사본을 반환하는 기능 만 정렬 된, Reveresed는 괜찮은 기본 Python 목록을 반환합니다. 반면에 정렬 및 리버스는 목록 자체에서 작동하며 유형을 유지합니다.

class myList(list):
    def __new__(cls, data=None):
        obj = super(myList, cls).__new__(cls, data)
        return obj

    def __str__(self):
        return 'myList(%s)' % list(self)

    def __add__(self, other):
        return myList(list(self) + list(other))

>>> l = myList(range(5))
>>> print l
myList([0, 1, 2, 3, 4])
>>> print l + [1, 2]
myList([0, 1, 2, 3, 4, 1, 2])
>>> l.sort()
>>> print l
myList([0, 1, 2, 3, 4])

다른 팁

당신이 무시하고 싶다면 __str__ 다른 컨테이너의 경우 (예 : tuple), 여러 상속을 활용할 수 있습니다.

class PrettyStr(object):
    def __str__(self):
        ret = ''

        if isinstance(self, (list, tuple)):
            ret = ''.join(str(elem) for elem in self)
        else:
            pass  # handle other types here

        return ret


class MyList(PrettyStr, list):
    pass


class MyTuple(PrettyStr, tuple):
    pass


if __name__ == "__main__":
    print MyList([1, 2, 3, 4])
    print MyTuple((1, 2, 3, 4))

목록 클래스를 확장하고 재정의 할 수 있습니다.

class myList(list):
  def __str__(self):
    # do something
    return "something"

편집 : 동적 교체를 제안하는 답의 잘못된 부분을 제거했습니다. __str__ Python 목록의 구현에서 허용되지 않는 목록 개체에서.

나는 Java 프로그래머이지만 그것이 당신이 원하는 것이라고 생각합니다 (Python 2.6으로 테스트) :

>>> class myList(list):
...   def __str__(self):
...     return "aaa"
...
>>> def myListWrapper(list):
...   return myList(list)
...
>>> a = [1, 2, 3]
>>> type(a)
<type 'list'>
>>> b = myListWrapper(a)
>>> type(b)
<class '__main__.myList'>
>>> print(a)
[1, 2, 3]
>>> print(b)
aaa
class MyList(list):
     def __str__(self):
             return "foo"

str(MyList([1, 2, 3]))

'foo'

str(MyList(list([1, 2, 3])))

'foo'

답으로서의 이전 의견. 보시다시피 MyList는 생성자에서 모든 시퀀스를 수락합니다.

질문을 제기하는 것은 다음과 같습니다. 왜 __str__ 메소드를 무시하고 싶습니까?

객체를 캡슐화하기 위해 클래스를 만드는 것이 더 낫지 않습니까?

class MyContainer(object):
    def __init__(self, list):
        self.containedList = list

    def __str__(self):
        print('All hail Python')

이렇게하면 객체를 변환하거나 속성을 복사하는 것에 대해 걱정할 필요가 없습니다. (그건 그렇고, MyList (Longlist)는 얼마나 비싸나요? 지능형 사본입니까, 아니면 바보입니까?

어느 시점에서, 당신이하려는 일을하는 것이 복잡해 보이면, 당신이 잘못하고 있다는 것을 의미 할 수 있습니다 : P

목록을 포장하는 것은 어떻습니까?

>>> class StrList(object):
    def __init__(self, data=None):
        self._data = data or []
    def __str__(self):
        return "StrList!"
    def __getattr__(self, attr):
        if attr == "_data":
            return self.__dict__[attr]
        return getattr(self._data, attr)
    def __setattr__(self, key, val):
        if key == "_data":
            self.__dict__[key] = val
        else:
            setattr(self._data, key, val)
    def __getitem__(self, index):
        return self._data[index]
    def __setitem__(self, index, value):
        self._data[index] = value


>>> l = StrList(range(3))
>>> print l
StrList!
>>> l[0]
0
>>> for x in l:
    print x


0
1
2
>>> l[0] = "spam"
>>> l.append("egg")
>>> print list(l)
['spam', 1, 2, 'egg']
>>> 
Ex = ["a", 2, 4] #our_list
Ex(-1) = "xuxu_beleza" #the_name_of_your_list(index) = new_item 
Print(Ex) 
["a", 2, "xuxu_beleza"] #our_new_list

**list[index] = new_item**
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top