python: изменить печать класса [дубликат]

этот вопрос уже есть ответ здесь:

возможно ли в python изменить то, что печатается для классов. Я знаю, что если мы предоставим __str__ __unicode__ методы, мы можем изменить способ печати экземпляров класса. Но я хотите сделать это для класса

например:

class A(object):
    def __str__(self):
        return 'hello'

a = A()
print a

печати hello. Можно ли изменить поведение print A который по умолчанию печатает что-то вроде <class '__main__.A'>

обновление: я думаю, я мог бы также объяснить контекст. Я пытаюсь создавать запросы MySQL и у меня есть классы, представляющие таблицы. Каждый из этих табличных классов имеет переменную класса, содержащую имя таблицы. Так что я хочу сделать, чтобы иметь возможность передать класс как параметр для курсора.выполните и замените имена таблиц в запросе.

2 ответов


да, предоставив метакласс. Это плохая идея, потому что метаклассы не очень хорошо сочиняют, и это волшебно и запутанно.

>>> class A(type):
...     def __repr__(self):
...             return '<this is not a class!>'
...
>>> class B(object):
...     __metaclass__ = A
...
>>> print B
<this is not a class!>

(вы можете изменить __str__ также это зависит от семантики того, что это такое)


вы обновили свой пост, чтобы рассказать о создании SQL-запросов из класса. Вместо изменения str(Class), почему бы вместо этого не использовать Class.__name__ (т. е. имя, с которым вы его определили), или, возможно,Class.table_name (т. е. какого-то класса атрибут, который вы определяете для каждого класса)? Возможность проходить в классах и автоматически работать как имена таблиц, которые не имеют формы <class 'foo.x'> потенциально очень запутанно для будущих читателей вашего кода, потому что неясно, что это должно работать из контекста. Читатель должен помнить, что были задействованы хаки метакласса (относительно редкая вещь, хотя и не в ORMs!) и что сделал хакер metaclass. Напротив, просто проходя Class.table_name вместо Class делает его очень очевидным, что продолжающийся.


достаточно легко с помощью метакласса. Метакласс относится к классу, как класс относится к экземпляру

class A_meta(type):
    def __str__(cls):
        return 'foobar'


class A(object):
    __metaclass__ = A_meta
    def __str__(self):
        return 'hello'

a = A()
print a
print A