There are multiple flags on each DAG node that define the visibility of the object on screen.
DAG objects are part of the scene graph, so visibility of the parent nodes affect children too.
This makes it hard to track what is going on.

Here is a compact snippet of code that reliably provides the visibility state:

def isVisible(node):

  nodes = [node]
  while True:
      node = mc.listRelatives(node, pa=True, p=True)[0]
    except: break

  override = False
  for node in nodes:
    if mc.objExists(node+".v"):
        if not mc.getAttr(node+".v"): return False
    if mc.objExists(node+".io"):
        if mc.getAttr(node+".io"): return False
    if mc.objExists(node+".lodv"):
        if not mc.getAttr(node+".lodv"): return False
    if not override:
      if mc.objExists(node+".ove"):
          override = mc.getAttr(node+".ove")
          if override and not mc.getAttr(node+".ovv"): return False

  return True
Quote 0 0
Figured i should add this for completeness:
One can use the `ls` command with "-v" flag to filter only visible dag objects.
The result will be similar to the code snippet from my previous post.
Quote 1 0