Я не уверен, что вопрос точно отражает мою дилемму. Экземпляры Film
на самом деле не связаны в цепочке родительского MRO Director, поскольку они не наследуются от этого класса.
С этим связано множество проблем, не в последнюю очередь из которых, как я исследую, как рефакторинг это для использования с SQLAlchemy. Простую стандартную библиотеку (3.7) dataclass
declarative
легко построить, и она хорошо работает, даже с миксинами и в виде смешанных, но причудливые кусочки ассоциативных отношений в классах Python, представленные здесь, остаются для меня в значительной степени загадка с чем-то вроде едва достижимого горизонта.
На пути к этому рассвету самая большая проблема здесь, помимо размещения классов для рефакторинга для использования с SQLAlchemy, - это присвоение Director
instance id
к каждому из фильмов.
Если у вас есть понимание порядка вывода, это было бы здорово. Таким образом, порядок сохраняется в соответствии с порядком объявления в классе, но он уничтожается тем фактом, что любой атрибут со значением по умолчанию не должен предшествовать любому, который инициализируется автоматически, то есть порядок в объявлении учитывается в зависимости от того, как получено значение .
Извините, если это немного грязно. Это бесплатно sh из заметок, и не было предпринято никаких усилий, чтобы уменьшить его.
Любые другие вопросы / ответы, которые вы можете задать в отношении автономной оптимизации рефакторинга, и в теоретическом контексте SQLAlchemy, все очень очень признателен. Я сделаю все, что в моих силах, чтобы отредактировать это, если есть интерес к рассылке лучших практик здесь.
На дополнительном примечании у меня возникли проблемы с импортом InitVar
. Поскольку я использую Python 3.6.9
, а dataclasses
устанавливается через pip install dataclasses
, мне интересно, решена ли это известная проблема, связанная со стандартным внедрением библиотеки в Python 3.7
, или, вероятно, что-то уникальное для меня?
Поскольку я продолжаю работать над этим, я ищу указатели о том, как обращаться с датами. Обратите внимание на дату рождения директоров здесь, висят как комментарии. Для date
нет типа класса данных, и, если я не ошибаюсь, Any
из библиотеки typing
, тот же самый List
, с заглавной буквы 'L', будет способствовать автоматической инициализации, требуется запись на создание экземпляра класса. Для этого также необходимо рассчитать возраст по введенной дате рождения.
Импорт
from dataclasses import dataclass, field, asdict, astuple
from typing import ClassVar, List, Any
import pprint
from pprint import PrettyPrinter
pp = pprint.PrettyPrinter(indent=4)
@dataclass
class Film:
_films_count: ClassVar = 0
_films_list: ClassVar = []
name: str
year: str
director_id: int = field(default_factory = int, init=False)
# film_list: list = field(default_factory = list)
film_tuple: tuple = field(default_factory = tuple)
id: int = field(init=False)
def __post_init__(self):
# director_id = Director.id
Film._films_count += 1
self.id = Film._films_count
# d_films = Films()
# d_films = Film("Lucy", 2016)
# print(d_films)
# print(asdict(d_films))
@dataclass
class Director:
_director_count: ClassVar = 0
_director_names: ClassVar = []
firstname: str
lastname: str
age: int
fullname: str = field(init=False)
film_list: List[Film] # = field(default_factory=list)
id: int = field(init=False)
def __post_init__(self):
# pass
Director._director_count += 1
self.id = Director._director_count
self.fullname = f"{self.firstname} {self.lastname}"
Director._director_names.append(self.getfullname())
Director._director_names.append(self.fullname)
def getfullname(self):
return self.fullname
@classmethod
def assign_id(cls):
print("Class ", cls)
return Director._director_count + 1
d_assign_id = Director.assign_id()
print("D_ID ",d_assign_id)
films = (Film("Lucy", 2014, d_assign_id), Film("5th Element", 1997, d_assign_id), Film("Anna", 2019, d_assign_id))
d = Director("Luc", "Besson", 60, films)
# March 18, 1959
d_assign_id = Director.assign_id()
films = (Film("Star Trek: Into Darkness", 2013, d_assign_id), Film("Mission Impossible III", 2006, d_assign_id), Film("Star Wars: The Force Awakens", 2015, d_assign_id))
e = Director("JJ", "Abrams", 53, films)
# June 27, 1966
print(d.getfullname())
print(d.__repr__())
print(Director._director_count)
dashed()
print(Director._director_names)
dashed()
for _ in Director._director_names:
print(_)
dashed()
pp.pprint(asdict(d))
dashed()
# pp.pprint(astuple(d))
# dashed()
# pp.print(Film._film_names[:])
pp.pprint(asdict(e))
Вывод
d_assign_id
не работает. В film_list.director_id
для каждой записи значение остается 0
. Как бы вы подошли к рефакторингу, чтобы он работал? Как бы вы описали отношения между классами на языке OO и, надеюсь, с метаданными таблицы lin go?
☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂
{ 'age': 60,
'film_list': ( { 'director_id': 0,
'film_tuple': 1,
'id': 1,
'name': 'Lucy',
'year': 2014},
{ 'director_id': 0,
'film_tuple': 1,
'id': 2,
'name': '5th Element',
'year': 1997},
{ 'director_id': 0,
'film_tuple': 1,
'id': 3,
'name': 'Anna',
'year': 2019}),
'firstname': 'Luc',
'fullname': 'Luc Besson',
'id': 1,
'lastname': 'Besson'}
☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂
{ 'age': 53,
'film_list': ( { 'director_id': 0,
'film_tuple': 2,
'id': 4,
'name': 'Star Trek: Into Darkness',
'year': 2013},
{ 'director_id': 0,
'film_tuple': 2,
'id': 5,
'name': 'Mission Impossible III',
'year': 2006},
{ 'director_id': 0,
'film_tuple': 2,
'id': 6,
'name': 'Star Wars: The Force Awakens',
'year': 2015}),
'firstname': 'JJ',
'fullname': 'JJ Abrams',
'id': 2,
'lastname': 'Abrams'}
☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂ # ☂
New Horizons
Итак, Ответ был опубликован в комментариях, и он содержит правильный, последовательно получаемый director_id
для каждого экземпляра класса Film
в пределах сгенерированного default_factory
List
. И это немного низкоуровневых магов c, которые должны быть зачтены умельцам PEP.
Продвигаясь, в Film
, этот метод экземпляра:
def getdirector_id(self):
return self.director_id
. .. с желанием получить доступ к Film
экземплярам, созданным в массовом порядке при вызове Director
, в соответствии с этим нерабочим примером:
print(Film.id[5].getdirector_id())
Имеется ли возможность уже и вызов Я делаю просто показывает недостаток знаний? Или метод экземпляра не является правильным подходом, или путь данных к элементу плохо понят / понят?