Как я могу гарантировать, что при создании экземпляра структуры данных в VSCode+Jupyter+Python атрибуты структуры данных будут доступны для автозаполнения во всем блокноте.
# %% Jupyter Cell #1
#This cell is executed before attempting autocompletes in cell 2
@dataclass
class ExistingItemNames:
pass
class SearchableItemNames:
def __init__(self, var_names:list):
self.names__ = ExistingItemNames()
for name in var_names:
setattr(self.names__, name, name)
self.names = self.names__.__dict__
si = SearchableItemNames([f"v{i}" for i in range(2000)])
# %% Jupyter Cell 2
#outside other data structures, accessing through a
# dict or attr seem equivalent
si.names['v1999'] #does not find 'v1999' key via autocomplete
si.names['v10'] # does find 'v10' key via autocomplete
si.names__.v1999 #does not find `v1999` attr via autocomplete
si.names__.v10 #does find `v10` attr via autocomplete
#inside of a data structure, the dict is required for autocompletion
# but still does not find all values
(si.names__.v1999) #does not find `v1999` attr via autocomplete
(si.names__.v10) #does not find `v10` attr via autocomplete
(si.names['v1999']) #does not find 'v1999' key via autocomplete
(si.names['v10']) # does find 'v10' key via autocomplete
Я понимаю, что исчерпывающее перечисление ключей или атрибутов не будет хорошим решением для всех случаев использования из-за ограничений сервера языка Python, но есть ли способ заставить IDE (VSCode+Jupyter) делать это только наверняка объекты в определенных средах Python или в определенных блокнотах Jupyter?
аналог stackoverflow.com/q/77228321/11107541 ?
Однозначно аналог. Я тоже положил туда свой ответ. Спасибо за указатель.
Основываясь на комментариях, я собрал это вместе. Идея состоит в том, чтобы заставить IDE автоматически заполнять все классы attr, нам нужно жестко запрограммировать атрибут attr. Мы можем динамически выполнить жесткое кодирование, создав файл .py, содержащий класс данных, используя str ops, а затем записав файл .py в тот же wd, что и .ipynb. Как только файл .py существует, мы можем загрузить составленный объект SearableItems в .ipynb, и IDE автоматически заполнит все его атрибуты. Хотелось бы увидеть более питонический способ добиться этого, поскольку этот код кажется мне немного нечестивым, но для моих целей он работает очень хорошо.
# %% Jupyter Cell 1
tmp_dict = {f"var_{i}":f'{i}' for i in range(2000)}
str_nums = {1:'one', 2:'two',
3:'three', 4:'four',
5:'five', 6:'six',
7:'seven', 8:'eight',
9:'nine'}
def write_searchable_items_py(items_dict, fname = 'searchable_items.py'):
if '.py' not in fname:
fname = fname + '.py'
dataclass_str = [f"""from dataclasses import dataclass, field
def get_vals():
return {items_dict}
@dataclass
class SearchableItems:""", ]
lines = []
for k in items_dict:
val = items_dict[k]
if k == '#':
k = f"pound_hashtag"
k = k.replace(" ", "_")
k = ''.join(c for c in k if c.isalnum() or c == '_')
if k[0].isnumeric():
if int(k[0]) in str_nums.keys():
#k = k + str_nums[int(k[0])]
k = str_nums[int(k[0])] + k[1:]
else:
k = "_" + k
lines.append(f"\t{k}:str = '{val}'")
dict_line = [f"\td: dict = field(default_factory = get_vals)", ]
dataclass_str = "\n".join(dataclass_str + lines + dict_line)
with open(fname, 'w') as f:
f.write(dataclass_str)
# %% Jupyter Cell 2
write_searchable_items_py(tmp_dict)
# %% Jupyter Cell 3
from searchable_items import SearchableItems
si = SearchableItems()
# %% Jupyter Cell 4
si.var_1999 #autocompletes
si.var_10 #autocompletes
(si.var_1999) #autocompletes
(si.var_10) #autocompletes
si.d['var_10'] #autocompletes
(si.d['var_10']) #autocompletes
si.d['var_1999'] #Finds some keys like 1999, but not 1999
(si.d['var_1999']) #Finds some keys like 1999, but not 1999
Динамичность
setattr()
резко контрастирует со статической природой средств проверки типов, и это тоже не очень-то питонично. Я не верю, что можно каким-либо образом передать эти динамические атрибуты Pyright/Pylance, за исключением написания блокаTYPE_CHECKING
, полного таких объявлений.