Search code examples
pythonvectorprintingmayapymel

Why when printing a vector is str(vector) implicitly called?


Everything below this paragraph is from the book Practical Maya Programming. In the second to last line the author says that the print statement with argument t implicitly calls str(t), I'd like to know why, also in the second block of code the author creates vect and assigns it to the value xform.translate.get(), couldn't he have just continued using t which is also assigned to xform.translate.get()?

>>> xform.translate
Attribute(u'pSphere1.translate')
>>> t = xform.translate.get()
>>> print t
[0.0, 0.0, 0.0]

The translation value of the sphere transform, which is highlighted, appears to be a list. It isn't. The translation value is an instance of pymel.core.datatypes.Vector. Sometimes we need to more aggressively introspect objects. I think this is one of the few areas where PyMEL made a mistake. Calling str(t) returns a string that looks like it came from a list, instead of looking like it came from a Vector. Make sure you have the correct type. I've spent hours hunting down bugs where I was using a Vector instead of a list, or vice versa.

>>> vect = xform.translate.get()
>>> lst = [0.0, 0.0, 0.0]
>>> str(vect)
'[0.0, 0.0, 0.0]'
>>> str(lst)
'[0.0, 0.0, 0.0]'
>>> print t, lst # The print implicitly calls str(t)
[0.0, 0.0, 0.0] [0.0, 0.0, 0.0]

Solution

  • That's because of Python's datamodel. According to the docs:

    object.__str__(self) Called by str(object) and the built-in functions format() and print() to compute the “informal” or nicely printable string representation of an object. The return value must be a string object.

    This method differs from object.__repr__() in that there is no expectation that __str__() return a valid Python expression: a more convenient or concise representation can be used.

    The default implementation defined by the built-in type object calls object.__repr__().

    So as you can see, Python's print(object) calls object.__str__() internally which returns the string representation of your object. Calling str(object) also returns object.__str__().

    Due to that fact, both print(object) and str(object) will give you the same visual output.