Как динамически устанавливать атрибуты объекта, используя списки внутри объекта класса данных?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 ... class-obje
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

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