Как динамически устанавливать атрибуты объекта, используя списки внутри объекта класса данныхPython

Программы на Python
Anonymous
Как динамически устанавливать атрибуты объекта, используя списки внутри объекта класса данных

Сообщение Anonymous »

В настоящее время у меня есть этот код, который в некоторых местах выглядит очень повторяющимся:

Код: Выделить всё

from dataclasses import dataclass, field

@dataclass
class Locator:
locator_attr: str
transform: str = field(init=False)
position: tuple = field(init=False)
point_on_curve: str = field(init=False)
normal_attr: str = field(init=False)
normal: tuple = field(init=False)
normalizedNormal_attr: str = field(init=False)
normalizedNormal: tuple = field(init=False)
tangent_attr: str = field(init=False)
tangent: tuple = field(init=False)
normalizedTangent_attr: str = field(init=False)
normalizedTangent: tuple = field(init=False)

def __post_init__(self) -> None:
self.transform = cmds.listConnections(f"{self.locator_attr}.locatorTransform")[0]
self.position = cmds.xform(self.transform, q=True, t=True, ws=True)
self.point_on_curve = cmds.listConnections(f"{self.locator_attr}.pointOnCurve")[0]
self.normal_attr = f"{self.point_on_curve}.normal"
self.normal = cmds.getAttr(f"{self.point_on_curve}.normal")[0]
self.normalizedNormal_attr = f"{self.point_on_curve}.normalizedNormal"
self.normalizedNormal = cmds.getAttr(f"{self.point_on_curve}.normalizedNormal")[0]
self.tangent_attr = f"{self.point_on_curve}.tangent"
self.tangent = cmds.getAttr(f"{self.point_on_curve}.tangent")[0]
self.normalizedTangent_attr = f"{self.point_on_curve}.normalizedTangent"
self.normalizedTangent = cmds.getAttr(f"{self.point_on_curve}.normalizedTangent")[0]
То же самое в разделе

Код: Выделить всё

    normal_attr: str = field(init=False)
normal: tuple = field(init=False)
normalizedNormal_attr: str = field(init=False)
normalizedNormal: tuple = field(init=False)
tangent_attr: str = field(init=False)
tangent: tuple = field(init=False)
normalizedTangent_attr: str = field(init=False)
normalizedTangent: tuple = field(init=False)
И

Код: Выделить всё

        self.normal_attr = f"{self.point_on_curve}.normal"
self.normal = cmds.getAttr(f"{self.point_on_curve}.normal")[0]
self.normalizedNormal_attr = f"{self.point_on_curve}.normalizedNormal"
self.normalizedNormal = cmds.getAttr(f"{self.point_on_curve}.normalizedNormal")[
0
]
self.tangent_attr = f"{self.point_on_curve}.tangent"
self.tangent = cmds.getAttr(f"{self.point_on_curve}.tangent")[0]
self.normalizedTangent_attr = f"{self.point_on_curve}.normalizedTangent"
self.normalizedTangent = cmds.getAttr(
f"{self.point_on_curve}.normalizedTangent"
)[0]
Термины ['normal','normalizedNormal','tangent','normalizedTangent'] повторяются, и в случае, если я захочу добавить новый атрибут, мне придется изменить множество строк.
Я попробовал создать список внутри класса, поэтому добавить атрибут можно было, только добавив его в список:

Код: Выделить всё

_node_attrs:list = field(default_factory=['normal','normalizedNormal','tangent','normalizedTangent'])

Код: Выделить всё

from dataclasses import dataclass, field

@dataclass
class Locator:
locator_attr: str
transform: str = field(init=False)
position: tuple = field(init=False)
point_on_curve: str = field(init=False)
_node_attrs:list = ['normal','normalizedNormal','tangent','normalizedTangent']
for _attrname in _node_attrs:
globals()[f'{_attrname}_attr']: str = field(init=False)
globals()[f'{_attrname}']: tuple = field(init=False)
def __post_init__(self) ->  None:
self.transform = cmds.listConnections(f"{self.locator_attr}.locatorTransform")[0]
self.position = cmds.xform(self.transform, q=True, t=True, ws=True)
self.point_on_curve = cmds.listConnections(f"{self.locator_attr}.pointOnCurve")[
0
]
Если список представляет собой поле, я получаю сообщение об ошибке:

Код: Выделить всё

# Error: 'Field' object is not iterable
# Traceback (most recent call last):
#   File "", line 3, in 
#   File "", line 10, in Locator
# TypeError: 'Field' object is not iterable #
но если я перейду на простой список, то получу

Код: Выделить всё

# Error: mutable default  for field _node_attrs is not allowed: use default_factory
# Traceback (most recent call last):
#   File "", line 3, in 
#   File "C:\Program Files\Autodesk\Maya2022\Python37\lib\dataclasses.py", line 1010, in dataclass
#     return wrap(_cls)
#   File "C:\Program Files\Autodesk\Maya2022\Python37\lib\dataclasses.py", line 1002, in wrap
#     return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
#   File "C:\Program Files\Autodesk\Maya2022\Python37\lib\dataclasses.py", line 850, in _process_class
#     for name, type in cls_annotations.items()]
#   File "C:\Program Files\Autodesk\Maya2022\Python37\lib\dataclasses.py", line 850, in 
#     for name, type in cls_annotations.items()]
#   File "C:\Program Files\Autodesk\Maya2022\Python37\lib\dataclasses.py", line 733, in _get_field
#     raise ValueError(f'mutable default {type(f.default)} for field '
# ValueError: mutable default  for field _node_attrs is not allowed: use default_factory #
Какой самый простой способ сделать это с помощью класса данных?


Подробнее здесь: https://stackoverflow.com/questions/786 ... ass-object

Вернуться в «Python»