class_docstr: Associative operations, can separate noncommutative and
  commutative parts.
  
  (a op b) op c == a op (b op c) == a op b op c.
  
  Base class for Add and Mul.
  
  This is an abstract base class, concrete derived classes must define
  the attribute `identity`.
  
  .. deprecated:: 1.7
  
     Using arguments that aren't subclasses of :class:`~.Expr` in core
     operators (:class:`~.Mul`, :class:`~.Add`, and :class:`~.Pow`) is
     deprecated. See :ref:`non-expr-args-deprecated` for details.
  
  Parameters
  ==========
  
  *args :
      Arguments which are operated
  
  evaluate : bool, optional
      Evaluate the operation. If not passed, refer to ``global_parameters.evaluate``.
docstr: Evaluate the parts of self that are numbers; if the whole thing
  was a number with no functions it would have been evaluated, but
  it wasn't so we must judiciously extract the numbers and reconstruct
  the object. This is *not* simply replacing numbers with evaluated
  numbers. Numbers should be handled in the largest pure-number
  expression as possible. So the code below separates ``self`` into
  number and non-number parts and evaluates the number parts and
  walks the args of the non-number part recursively (doing the same
  thing).
docstr_tok: ["Evaluate","the","parts","of","self","that","are","numbers",";","if","the","whole","thing","was","a","number","with","no","functions","it","would","have","been","evaluated",",","but","it","was","n't","so","we","must","judiciously","extract","the","numbers","and","reconstruct","the","object",".","This","is","*","not","*","simply","replacing","numbers","with","evaluated","numbers",".","Numbers","should","be","handled","in","the","largest","pure-number","expression","as","possible",".","So","the","code","below","separates","``","self","``","into","number","and","non-number","parts","and","evaluates","the","number","parts","and","walks","the","args","of","the","non-number","part","recursively","(","doing","the","same","thing",")","."]
code: def _eval_evalf(self, prec):
      """
      Evaluate the parts of self that are numbers; if the whole thing
      was a number with no functions it would have been evaluated, but
      it wasn't so we must judiciously extract the numbers and reconstruct
      the object. This is *not* simply replacing numbers with evaluated
      numbers. Numbers should be handled in the largest pure-number
      expression as possible. So the code below separates ``self`` into
      number and non-number parts and evaluates the number parts and
      walks the args of the non-number part recursively (doing the same
      thing).
      """
      from .add import Add
      from .mul import Mul
      from .symbol import Symbol
      from .function import AppliedUndef
  
      if isinstance(self, (Mul, Add)):
          x, tail = self.as_independent(Symbol, AppliedUndef)
          # if x is an AssocOp Function then the _evalf below will
          # call _eval_evalf (here) so we must break the recursion
          if not (
              tail is self.identity
              or isinstance(x, AssocOp)
              and x.is_Function
              or x is self.identity
              and isinstance(tail, AssocOp)
          ):
              # here, we have a number so we just call to _evalf with prec;
              # prec is not the same as n, it is the binary precision so
              # that's why we don't call to evalf.
              x = (
                  x._evalf(prec)
                  if x is not self.identity
                  else self.identity
              )
              args = []
              tail_args = tuple(self.func.make_args(tail))
              for a in tail_args:
                  # here we call to _eval_evalf since we don't know what we
                  # are dealing with and all other _eval_evalf routines should
                  # be doing the same thing (i.e. taking binary prec and
                  # finding the evalf-able args)
                  newa = a._eval_evalf(prec)
                  if newa is None:
                      args.append(a)
                  else:
                      args.append(newa)
              return self.func(x, *args)
  
      # this is the same as above, but there were no pure-number args to
      # deal with
      args = []
      for a in self.args:
          newa = a._eval_evalf(prec)
          if newa is None:
              args.append(a)
          else:
              args.append(newa)
      return self.func(*args)
  
imports: from __future__ import annotations
  from operator import attrgetter
  from collections import defaultdict
  from sympy.utilities.exceptions import sympy_deprecation_warning
  from .sympify import _sympify, sympify
  from .basic import Basic
  from .cache import cacheit
  from .sorting import ordered
  from .logic import fuzzy_and
  from .parameters import global_parameters
  from sympy.utilities.iterables import sift
  from sympy.multipledispatch.dispatcher import Dispatcher, ambiguity_register_error_ignore_dup, str_signature, RaiseNotImplementedError
label_desc: Use image node_id 7 for calling the AssocOp obj's underlying member method code with example usage: obj._eval_evalf(prec) and returns: self, self