2010-09-25 3 views
3

Я бы хотел изменить поведение отображения списка Python, чтобы вместо создания list они создавали подкласс list, который я написал. (Примечание: Я не думаю, что это хорошая идея, я делаю это для удовольствия, а не фактическое использование.)Могу ли я переопределить отображение списка Python?

Вот что я сделал:

old_list = list 

class CallableList(old_list): 
    def __init__(self, *args): 
     old_list.__init__(self) 
     for arg in args: 
      self.append(arg) 
    def __call__(self, start, end=None): 
     if end: 
      return self[start:end] 
     return self[start] 

list = CallableList 

После того, как это сделано, это возвращает третий элемент списка:

x = list(1, 2, 3) 
print x(2) 

, но это по-прежнему выдает ошибку:

x = [1, 2, 3] 
print x(2) 

ошибка довольно проста :

Traceback (most recent call last): 
    File "list_test.py", line 23, in <module> 
    print x(2) 
TypeError: 'list' object is not callable 

Я думаю, что, вероятно, нет способа сделать это, но я не могу найти ничего, что бы говорило так окончательно. Есть идеи?

+1

Вам не нужно переопределять конструктор вообще, потому что вы не меняете способ создания списка, вы просто добавляете метод. – aaronasterling

+3

@AaronMcSmooth: вы не можете добавлять методы к типам, определенным на C, например, к встроенному «списку». –

+0

Не '__init__' должен возвращать новый объект? – badp

ответ

3

Вы не можете тривиально переопределить синтаксический сахар, используемый для встроенных типов, поскольку это происходит на уровне компилятора. Всегда вызывайте конструктор явно.

+0

Это правда. Также кажется, что вы ищете список .__ getitem __ (x): L .__ getitem __ (x) <==> L [x] – inspectorG4dget

1

Вы не можете изменить его изнутри Python. В таких конструкциях, как list-comprehensions, всегда используется встроенный тип списка, а не то, что вы определили в нашем пространстве имен слово list. Если вы хотите изменить встроенный тип, вам нужно отредактировать исходный код Python и перекомпилировать. Предполагая, что вы используете реализацию CPython, она живет в Objects/listobject.c.

+0

Или вы могли бы написать свой собственный компилятор в Python. Python действительно предоставляет возможности для этого. –

-1
>>> print(x(2)) # works in 2.7 
    3 
    >>> type(x) 
    <class '__main__.CallableList'> 
    >>> y = [1,2,3] 
    >>> type(y) 
    <type 'list'> 

так вы на самом деле не переопределены типа «список», вы только изменили свое пространство имен, так что список списка типов в методе() теперь конфликтует с типом типа CallableList. Чтобы этого избежать,

>>> fred = CallableList 
    >>> type(fred) 
    <type 'type'> 
    >>> x = fred(1,2,3) 
    >>> x 
    [1, 2, 3] 
    >>> print x(2) 
    3 
    >>> 
Смежные вопросы