Retrieve the attribute of UI element by given attribute name. Return None if attribute does not exist.
        If attribute type is :obj:`str`, it is encoded to utf-8 as :obj:`str` in Python2.7.

        Args:
            name: 
                attribute name, it can be one of the following or any other customized type implemented by SDK

                - visible: whether or not it is visible to user
                - text: string value of the UI element
                - type: the type name of UI element from remote runtime
                - pos: the position of the UI element
                - size: the percentage size [width, height] in range of 0~1 according to the screen
                - name: the name of UI element
                - ...: other sdk implemented attributes

        Returns:
            None if no such attribute or its value is None/null/nil/etc. Otherwise the attribute value is returned. The
            returned value type is json serializable. In both py2 and py3, if the attribute value in remote is a
            text-like object, the return value type will be :obj:`str`.

        Raises:
            PocoNoSuchNodeException: when the UI element does not exists

        .. note:: Exception :py:class:`NodeHasBeenRemovedException` is caught automatically.
        
        See Also:
            :py:meth:`UI element attributes in poco sdk definition <poco.sdk.AbstractNode.AbstractNode.getAttr>`.

def attr(self, name):
        """
        Retrieve the attribute of UI element by given attribute name. Return None if attribute does not exist.
        If attribute type is :obj:`str`, it is encoded to utf-8 as :obj:`str` in Python2.7.

        Args:
            name: 
                attribute name, it can be one of the following or any other customized type implemented by SDK

                - visible: whether or not it is visible to user
                - text: string value of the UI element
                - type: the type name of UI element from remote runtime
                - pos: the position of the UI element
                - size: the percentage size [width, height] in range of 0~1 according to the screen
                - name: the name of UI element
                - ...: other sdk implemented attributes

        Returns:
            None if no such attribute or its value is None/null/nil/etc. Otherwise the attribute value is returned. The
            returned value type is json serializable. In both py2 and py3, if the attribute value in remote is a
            text-like object, the return value type will be :obj:`str`.

        Raises:
            PocoNoSuchNodeException: when the UI element does not exists

        .. note:: Exception :py:class:`NodeHasBeenRemovedException` is caught automatically.
        
        See Also:
            :py:meth:`UI element attributes in poco sdk definition <poco.sdk.AbstractNode.AbstractNode.getAttr>`.
        """

        # to optimize performance speed, retrieve only the first matched element.
        # 优化速度，只选择第一个匹配到的节点
        nodes = self._do_query(multiple=False)
        val = self.poco.agent.hierarchy.getAttr(nodes, name)
        if six.PY2 and isinstance(val, six.text_type):
            # 文本类型的属性值，只在python2里encode成utf-8的str，python3保持str类型
            # 这是为了在写代码的时候，无论py2/3始终可以像下面这样写
            # node.attr('text') == '节点属性值'
            val = val.encode('utf-8')
        return val