Форум сайта python.su
0
Имеем:
@dataclass class CounterData: counter_id: str period_start: datetime period_end: datetime counter_name: str = "" enter_count: int = 0 exit_count: int = 0 class SensorData: def __init__(self, sensor_type: str, sensor_serial: str, counter_data: list[CounterData], sensor_name: str = ""): self.sensor_serial = sensor_serial self.sensor_name = sensor_name self.sensor_type = sensor_type self.counters = counter_data def __str__(self): txt = f'SensorType={self.sensor_type}, SerialNumber={self.sensor_serial}, SensorName={self.sensor_name}' if len(self.counters) == 0: txt += '\t No counters data.' else: for counter in self.counters: txt += f'\n\tcounter_id={counter.counter_id}, counter_name={counter.counter_name}' \ f'\n\t\tperiod= {counter.period_start} - {counter.period_end}' \ f'\n\t\tentered= {counter.enter_count} exited= {counter.exit_count}' return txt def add_counter_data(self, counter_data: CounterData): self.counters.append(counter_data)
def parse_xml(file_name_full: str) -> SensorData | None: try: xml_tree = ElementTree.parse(file_name_full) except ElementTree.ParseError as err: print(repr(err)) return None xml_root = xml_tree.getroot() namespace = {'ns': 'http://www.tralivali.com/api/v2'} s_type = '3Dv2' s_serial = xml_root.find('ns:sensor-info/ns:serial-number', namespace).text if not s_serial: return None s_name = file_name_full sensor_data = SensorData(sensor_serial=s_serial, sensor_name=s_name, sensor_type=s_type) count_lines = xml_root.findall('ns:content/ns:elements/ns:element', namespace) for count_line in count_lines: line_measurements = count_line.findall('ns:measurements/ns:measurement', namespace) for measurement in line_measurements: enter_count = int(measurement.find("ns:values/ns:value[@label='fw']", namespace).text) exit_count = int(measurement.find("ns:values/ns:value[@label='fw']", namespace).text) line_count_data = CounterData( counter_id=count_line.find("ns:element-id", namespace).text, period_start=datetime.fromisoformat(count_line.find("ns:from", namespace).text), period_end=datetime.fromisoformat(count_line.find("ns:to", namespace).text), counter_name=count_line.find("ns:element-name", namespace).text, enter_count=enter_count, exit_count=exit_count ) sensor_data.add_counter_data(line_count_data) if len(sensor_data.counters) == 0: return None else: return sensor_data
... sensor_count_data: Optional[SensorData] = parse_xml(file_name_full) ...
line_count_data = CounterData(.....
Отредактировано kambi (Дек. 7, 2022 11:47:46)
Офлайн
857
kambiВ этой строке где четвёртый аргумент counter_data?sensor_data = SensorData(sensor_serial=s_serial, sensor_name=s_name, sensor_type=s_type)
Офлайн
0
Сорри, это я успел немного определение функции переделать) У меня там было так, со значением по умолчанию:
def __init__(self, sensor_type: str, sensor_serial: str, counter_data: list[CounterData] = [], sensor_name: str = "")
Офлайн
0
Думал уже может датаклассы как-то по особому иногда работают). Просто хочу понять причину.
Офлайн
857
kambiПотому что там этот список пустой не заменяется на новый список никогда. По мере добавления в него элементов они туда добавляются просто и всё.
Объясните, пож-та, кто-нибудь почему в объекте sensor_count_data: Optional = parse_xml(file_name_full) поле списка counters (тип CounterData) с каждой итериацией не очищается, а пополняется всен время новыми данными?
kambi
Просто хочу понять причину.
>>> def f(n, lst=[]): ... lst.append(n) ... return lst ... >>> f(1) [1] >>> f(2) [1, 2] >>> f(3) [1, 2, 3] >>> >>> f(4, []) [4] >>> f(5) [1, 2, 3, 5] >>> >>> f(6, []) [6] >>> f(7, []) [7] >>>
Офлайн
0
py.user.nextЭто правило относится только к значениям по-умолчанию, конкретно к list-ам или как? Где бы про это почитать?
Потому что там этот список пустой не заменяется на новый список никогда. По мере добавления в него элементов они туда добавляются просто и всё.
Офлайн
857
kambiСписок создаётся там, где определяется функция. Затем ссылка на этот объект присваивается в качестве значения по умолчанию для именованного аргумента функции. Объект продолжает существовать, пока есть хотя бы одна ссылка на него, привязанная к чему-то.
Это правило относится только к значениям по-умолчанию
kambiОбъекты описаны здесь
Где бы про это почитать?
kambiОн создаётся снаружи функции прямо в её определении. Потом происходит привязка к имени вот эта. И вот эта привязка действует потом, пока существует функция. И функция тоже является объектом. Пока объект функция живой, все привязки имён к объектам в нём также сохраняются. При передаче аргумента в функцию происходит перепривязка, но старая привязка также сохраняется и ждёт, когда функция будет вызвана без аргумента на этом месте.
объект создается внутри функции локально
kambiФункция создаётся один раз в месте определения и становится объектом. А вызывается потом много раз один этот объект, который был создан в первый раз.
Снова вызвали функцию - снова создали объект
>>> def f(n): ... f.x += 10 ... return n ... >>> f.x = 0 >>> >>> f(1) 1 >>> f(2) 2 >>> f(3) 3 >>> >>> f.x 30 >>>
Отредактировано py.user.next (Дек. 8, 2022 00:33:59)
Офлайн
0
Всё. Свой по своему случаю я кажется четко понял суть)). Спасибо.
Офлайн