I want to create a class, and I don’t want its attributes to be modified after new, so I choose NamedTuple,
But I hope that It can do something immediately after initialize,
So I hope to I can override the __init__ method,
but if I do this, I will encounter AttributeError: Cannot overwrite NamedTuple attribute __init__.
Is there any elegant code that can do it?
My actual case is to initialize the style of ttk, as follows.
import tkinter as tk
from tkinter import ttk
from typing import NamedTuple
class TTKStyle(NamedTuple):
LF_NORMAL = f'Normal.TLabelframe'
def init_style(self):
style = ttk.Style()
style.configure(self.LF_NORMAL, background='#FFFF00')
style.configure(f'{self.LF_NORMAL}.Label', foreground='red', background='blue', font=('courier', 15, 'bold'))
root = tk.Tk()
ttk_style = TTKStyle()
ttk_style.init_style() # <-- I don't want to write this line.
lf_exif = ttk.LabelFrame(root, text='EXIF Tag', style=ttk_style.LF_NORMAL)
lf_exif.pack()
tk.Label(lf_exif, text='ExifVersion').pack()
root.mainloop()
Decorator
You can use the decorator to help you.
__slots__
or you can use normal class and add
__slots__and put your init function on__init__directly (see class Person3), for example:The class of all the above attributes is read-only (for 2 and 3, you can change it from the class but not change from instance) and not accept other new attributes.