【问题标题】:Using several methods inside class在类中使用几种方法
【发布时间】:2018-05-28 10:54:49
【问题描述】:

目前,如果我输入x = Matrix([[5, 4], [3, 8]]),它正在调用__str__。我如何让它用这个输入调用另一个方法?

class Matrix(object):
    def __init__(self, matrix = 0):
        self.matrix = matrix

    def __Matrix__(self):
        return 10

    def __str__(self):
        return "\\n".join(["\\t".join
                       (["%d" % k for k in row]) for row in self.matrix])

如果我的输入是x = Matrix([[5, 4], [3, 8]]),我如何告诉程序调用方法__Matrix__?它目前正在调用__str__

我试图在“Matrix”类中创建一个“Matrix”方法,但程序没有改变,它继续使用__str__ 方法。

【问题讨论】:

  • 在询问之前先搜索stackoverflow.com/questions/7022211/… 在矩阵内部我只看到一个返回,请在进入 self/__methods 等之前重新学习 python 基础知识或以清晰的方式给我们代码、输入和预期输出我们可以为您提供帮助。
  • 我知道如何将输入的数字转换为数组/矩阵。我试图理解的是为什么程序一直使用 __ str __ 而不是使用 __ Matrix __ (并做它里面的任何事情)。
  • 因为 str 是内置的,甚至没有调用矩阵?
  • Python 应该如何知道它应该使用您的 __Matrix__ 方法来打印 Matrix 实例? FWIW,Python 提供了 3 种创建字符串表示的特殊方法:__str____repr____format__。您可以在Basic customization 中了解它们。顺便说一句,你的__str__ 有点奇怪。为什么你有"\\n""\\t" 而不是"\n""\t"
  • 这不是常规的 __ str __,我需要字符串的格式为 1\t2\n\4\t5。

标签: python


【解决方案1】:

Python 无法知道它应该使用您的 __Matrix__ 方法来打印 Matrix 实例。处理special method names 的方式是一种内部语言特性,您不能只添加新的特殊方法名称或更改现有方法名称的处理方式,而无需修改 Python 源代码并编译您自己的版本。除非您真的需要,否则这样做通常不是一个好主意。 ;)

正如我上面提到的,__str__ 应该返回一个适合显示给用户的字符串,因此通过__str__ 返回包含'\\t''\\n' 的序列可能不是一个好主意。我想您可以通过__repr__ 将其退回,但这仍然有点奇怪,恕我直言。我强烈建议你给它一个新名字,比如esc_str


只是为了好玩,我为你的班级实现了一个相对简单的__format__ 方法。这个特殊的方法被format 内置函数和str.format 方法调用。它也被新的 f-string 语法调用。

我的__format__ 方法确定矩阵每一列所需的最小宽度,您可以提供一个数字格式规范来设置所有列的最小宽度。添加了一个额外的空间来阻止列一起运行。您可以增强此方法以处理 format_spec 中的初始 '>' 或 '

class Matrix(object):
    def __init__(self, matrix = 0):
        self.matrix = matrix

    def __format__(self, minwidth):
        minwidth = int(minwidth) if minwidth else 0
        # Find maximum width of each column
        widths = [max(len(str(k)) for k in col) for col in zip(*self.matrix)]
        widths = [max(minwidth, u) for u in widths]
        result = []
        for row in self.matrix:
            result.append(" ".join(["%*d" % t for t in zip(widths, row)]))
        return "\n".join(result)

    def __repr__(self):
        return "Matrix(%s)" % self.matrix

    def __str__(self):
        return "\n".join(["\t".join(["%d" % k for k in row]) 
            for row in self.matrix])

    def esc_str(self):
        return r"\n".join([r"\t".join(["%d" % k for k in row]) 
            for row in self.matrix])

# test

m = Matrix([[1, 2, 3], [5, 4, 16], [9, 867, 0]])
print(repr(m))
print(m)
print(m.esc_str())
print('Matrix\n{:2}'.format(m))
print(f'Matrix\n{m}')

输出

Matrix([[1, 2, 3], [5, 4, 16], [9, 867, 0]])
1       2       3
5       4       16
9       867     0
1\t2\t3\n5\t4\t16\n9\t867\t0
Matrix
 1   2  3
 5   4 16
 9 867  0
Matrix
1   2  3
5   4 16
9 867  0

【讨论】:

  • 当你给Python m = Matrix([[1, 2, 3], [5, 4, 16], [9, 867, 0]]),然后是print(m),它怎么知道要使用哪种方法,因为你只是给它整个类的名称?
  • print 在它正在打印的对象上调用str。然后str如果存在则调用对象的__str__方法,否则调用__repr__。所有对象都应该有一个__repr__。如果一个类没有定义__repr__,则将使用它从其父类继承的那个,在许多情况下,这将是object 类中定义的默认__repr__
【解决方案2】:

你可以调用函数

print(x.__Matrix__())

它应该可以工作 如果您只是打印对象,它会自动调用内置函数 str

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 2017-06-27
    相关资源
    最近更新 更多