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.