【问题标题】:How to check if __str__ is implemented by an object如何检查 __str__ 是否由对象实现
【发布时间】:2019-10-13 16:01:02
【问题描述】:

如果对象尚未实现 __str__ 方法,我想在对象上动态实现它。

我尝试使用hasattr(obj, '__str__') 它总是返回真,因为它从对象类中获取它。

有没有办法确定一个对象是否真正实现了__str__

我知道我可以使用inspect.getmembers(obj),但我正在寻找一种更 Pythonic 的方式

编辑

class Employee(object):
def __init__(self, name, age, emp_code):
    self.name = name
    self.age  = age
    self.emp_code = emp_code

测试

e = Employee("A", 23, "E1")
print hasattr(e, '__str__')
>> True

我想要一个返回 False 的检查,而不是选择从 object 继承的方法。

【问题讨论】:

  • 我已经尝试将 hasattr 用于 'str' 但它总是返回 true。另一件事是,如果我将 hasattr 用于 'eq' 它工作正常
  • 检查obj.__str__ != object.__str__是否足够?
  • 您希望它适用于任何继承的__str__ 方法吗?如果方法不是来自object,而是继承链上的某个其他类怎么办?
  • “动态实现__str__”闻起来很可疑。你如何/为什么这样做?
  • 我希望你知道你不能将特殊方法monkeypatch到现有对象上; Python 不会检查实例的字典以查找特殊方法。

标签: python


【解决方案1】:

因为您要检查的是它是否有一个__str__ 实现,不是默认的object.__str__。因此,您可以这样做:

Foo.__str__ is not object.__str__

要检查实例化对象,您需要检查类:

type(f).__str__ is not object.__str__

即使 Foo 没有直接实现 __str__,而是从另一个类而不是 object 继承它,这也可以工作,这似乎是你想要的。

【讨论】:

  • is 而不是== 的良好示例用例。编辑:OP想要一些根本不寻找继承方法的东西。
  • 需要type(f).__dict__['__str__'] 来规避继承。嗯,dunders。
  • 奇怪的是,它甚至可以在你调用f = Foo(); f.__str__ = lambda: 'sneaky' 时工作,因为str(f) 不会调用f.__str__() (!)。
  • 不能在对象上实现特殊方法。只在他们的课上。
  • @Bhushan:在这种情况下,最好不要对对象执行 str(),而是自己创建方法。
【解决方案2】:

任何从object 基类继承的对象都将具有__str__ 方法,因此可以忽略它是否存在。

您可以在对象上存储一个标志属性,然后对其进行测试:

if not getattr(obj, 'has_str_override_flag'):
    override_str_here(obj)
    setattr(obj, 'has_str_override_flag', True)

【讨论】:

    【解决方案3】:

    在你的对象中有 __dict__ 包含对象所拥有的所有方法和变量。您可以检查给定对象是否具有由

    实现的 __str__() 方法
    '__str__' in Employee.__dict__
    

    '__str__' in vars(Employee)
    

    vars() 和 __dict__ 没有区别,只是 vars() 更 Pythonic。

    【讨论】:

      【解决方案4】:

      事实证明,内置类型依赖object.__str__ 进行(智能)格式化。我真的只想消除像<__main__.Foo object at 0x10299d390> 这样的无用字符串,并且仍然可以正确打印 dict 和其他类型。我的解决方案:

      objre = re.compile(r"<.* object at 0x[0-9a-f]+>")
      if objre.fullmatch(str(obj)):
          # Do smarter formatting
      

      这不会捕获模块、函数等的默认格式,其源代码可以通过inspect.getsource() 显示,但我不会在我的变量检查器中显示它们。

      【讨论】:

        【解决方案5】:

        使用 type(e).__dict__.get(method_name) 避免 KeyError 如果在使用 type(e).__dict__[method_name] 时类中不存在 method_name

        e = Employee("A", 23, "E1")
        if type(e).__dict__.get('__str__'):
            print('__str__ implemented')
        else:
            print('__str__ not implemented')
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-27
          • 1970-01-01
          • 2012-03-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多