code: def print_tree(self):
      from anytree import Node as AnyNode, RenderTree
  
      nodes = self._nodes
      anytree_nodes = {}
      for node in nodes:
          if not node.is_leaf:
              anytree_nodes[node.nid] = AnyNode(
                  name=f"{node.nid}: fid {node.fid}, bid {node.bid}, sample num {node.sample_num}, on {node.sitename}"
              )
          else:
              anytree_nodes[node.nid] = AnyNode(
                  name=f"{node.nid}: weight {node.weight}, sample num {node.sample_num}, leaf"
              )
      for node in nodes:
          if node.l != -1:
              anytree_nodes[node.l].parent = anytree_nodes[node.nid]
          if node.r != -1:
              anytree_nodes[node.r].parent = anytree_nodes[node.nid]
  
      for pre, _, node in RenderTree(anytree_nodes[0]):
          print("%s%s" % (pre, node.name))
  
imports: import numpy
  import pandas
  from fate.arch import Context
  from fate.arch.dataframe import DataFrame
  from fate.ml.ensemble.learner.decision_tree.tree_core.splitter import SplitInfo
  from typing import List
  import logging
label_desc: Use image node_id 18 for calling the DecisionTree obj's underlying member method code with example usage: obj.print_tree() without return types