Можно ли изменить поведение функции типа?

#python #built-in

Вопрос:

Мы можем изменить поведение str(object) функции, определив __str__ ее в классе объектов. Возможно ли это сделать с type помощью функции? Мне просто любопытно, ни одного подходящего случая.

Попытка с __class__ не работает:

 class A:
    def __class__(self):
        print(1)
        return "x"

obj = A()
print(type(obj))
 

он не печатает 1 и ничего с x ним не делает . Он просто печатает <class '__main__.A'> , как обычно.

Комментарии:

1. Вы можете изменить __class__ атрибут. Делать это, вероятно, не рекомендуется

2. @Lcj Я попробовал, и ничего не изменилось. Вы пробовали? Я думаю, что этот трюк работал несколько версий назад.

3. @PiotrWasilewicz Это сработало в моей оболочке 3.8.2 в режиме ожидания. Возможно, это работает только в определенных версиях.

4. @Lcj проверьте мой отредактированный вопрос. В вашем случае 1 печатается?

5. @PiotrWasilewicz Я имел в виду не определение __class__ метода, а установку __class__ атрибута. Пример obj.__class__ = B , затем тип(obj) вернет класс B.

Ответ №1:

Вы можете сделать это с помощью метакласса:

 
class Meta(type):
    def __repr__(cls):
        return "Fire"

class A(metaclass=Meta):
    pass

print(type(A()))
# Prints "Fire"
 

Комментарии:

1. Хорошо, это работает в какой-то степени. Когда я дал print(1) __repr__ (перед ответным «Огнем»), он не печатается при type(A()) вызове. Он печатается только с print(type(A())) таким образом , я думаю, что меняется только представление type , никакого type поведения.

2. Вызывается репортаж @PiotrWasilewicz print . Вы можете определить __init__ метод в метаклассе, который вызывается при инициализации типа.

3. Это не меняет того, что type происходит, только то, что вы видите при печати объекта типа. Определение __init__ в метаклассе также не меняет того, что type делает (по крайней мере, в примере OP; это может изменить поведение, когда type используется для построения класса).

4. @kaya3 Совершенно верно. С помощью этого метода можно изменить поведение типа объекта, но не поведение самой встроенной функции type .

5. пример с мышеловкой делает (я думаю) именно то, что __str__ делает метод изменения. Это не меняет str поведение, это меняет то, что str означает для этого одного класса. Это было то, чего я хотел. Мы можем использовать forbiddenfruit пакет для постоянных изменений.