Как получить дерево объектов относительно указанного объекта ? (Python)

Автор Тема: Как получить дерево объектов относительно указанного объекта ? (Python)  (Прочитано 2169 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн izhgtumekhanikАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 71
  • Карма: 0
  • Skype: izhgtumekhanik@gmail.com
Добрый день!

сам код:

Код - Python [Выбрать]
  1. from win32com.client import Dispatch, gencache
  2. import inspect
  3.  
  4. def filtr_obj(obj):
  5.     """Возвращает список имён COM-объектов, в которые можно зайти."""
  6.     tmp = []
  7.    
  8.     # получаем тип объекта
  9.     type_obj = str(type(obj))
  10.    
  11.     # если это com объект а не штатная функция
  12.     if "win32com" in type_obj and not inspect.isbuiltin(obj) and not inspect.isfunction(obj):
  13.        
  14.         listNames = dir(obj)
  15.         for iName in listNames:
  16.             if not iName.startswith("_") or not iName.endswith("_"):
  17.                 tmp.append(iName)
  18.    
  19.     return tmp
  20.  
  21. def explore(obj, path, depth, max_depth, results, visited):
  22.     """Рекурсивно обходит дерево объектов COM API."""
  23.     if depth > max_depth:
  24.         return
  25.  
  26.     for name in filtr_obj(obj):
  27.         full_path = f"{path}.{name}" if path else name
  28.  
  29.         try:
  30.             value = getattr(obj, name)
  31.         except Exception:
  32.             # Если не удаётся получить атрибут — просто записываем путь и идём дальше
  33.             results.append(full_path)
  34.             continue
  35.  
  36.         results.append(full_path)
  37.  
  38.         # Чтобы избежать зацикливания (одни и те же объекты в разных местах)
  39.         if id(value) not in visited:
  40.             visited.add(id(value))
  41.             explore(value, full_path, depth + 1, max_depth, results, visited)
  42.  
  43. # ------------------- Запуск -------------------
  44. AcadAPI = gencache.EnsureModule('{5B3245BE-661C-4324-BB55-3AD94EBBFDD7}', 0, 1, 0)
  45. AcadObject = Dispatch('AutoCAD.Application.21', None, AcadAPI.IAcadApplication.CLSID)
  46.  
  47. results = []
  48. visited = set()
  49. explore(AcadObject, AcadObject.__class__.__name__, 1, max_depth=30, results=results, visited=visited)
  50.  
  51. with open("acad_object_tree.txt", "w", encoding="utf-8") as f:
  52.     f.write("\n".join(results))
  53.  
  54. print(f"Объектов собрано: {len(results)}")
  55.  

столкнулся с проблемой зацикливания - вот пример:

IAcadApplication.ActiveDocument.ActiveDimStyle.Application.ActiveDocument.ActiveDimStyle.Application.ActiveDocument.Application. и так далее

в коде можно понять что идентификаторы объектов:
IAcadApplication.ActiveDocument
и
IAcadApplication.ActiveDocument.ActiveDimStyle.Application.ActiveDocument
разные! не пойму почему так выходит. в общем не как не могу выйти из замкнутого круга..

Оффлайн izhgtumekhanikАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 71
  • Карма: 0
  • Skype: izhgtumekhanik@gmail.com
Ау, вы что же там прячетесь ?

Оффлайн izhgtumekhanikАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 71
  • Карма: 0
  • Skype: izhgtumekhanik@gmail.com

Отмечено как Решение izhgtumekhanik 15-08-2025, 18:59:02

Оффлайн izhgtumekhanikАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 71
  • Карма: 0
  • Skype: izhgtumekhanik@gmail.com
В общем сделал проверку на уникальность str(type(obj)) в строке объектов - тут есть риск что часть полей объектов -> пропущено.

Больше не вижу вариантов.

Оффлайн izhgtumekhanikАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 71
  • Карма: 0
  • Skype: izhgtumekhanik@gmail.com
Но есть но, код очень медленный из за проверок что уже 2 час а он все собирает список.


Оффлайн izhgtumekhanikАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 71
  • Карма: 0
  • Skype: izhgtumekhanik@gmail.com
... шли 3 сутки - сгенерировано 19 500 000 объектов... скрипт продолжает работу..

в общем есть объекты "паразиты" ['ActiveDimStyle','Application', 'ActiveLayer', 'Database', 'ActiveLayout']

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 630
  • Карма: 161
    • ПГСу Бложик
Не понимаю, что Вы делаете, но дерево объектов есть в справке по VBA или легко ищется по фразе "AutoCAD Object Model" в любом поисковике.
Например: https://documentation.help/AutoCAD-ActiveX-AAG/WS1a9193826455f5ff1a32d8d10ebc6b7ccc-6cb4.htm