如何解决Python:如何初始化NamedTuple类
我想创建一个类,并且我不想在新建后修改其属性,所以我选择了NamedTuple
,
但是我希望它可以在初始化后立即做些事情,
但是,如果这样做,我会遇到 AttributeError:无法覆盖NamedTuple属性__init__
。
是否有任何优雅的代码可以做到?
我的实际情况是初始化ttk
的样式,如下所示。
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()
解决方法
装饰器
您可以使用装饰器来帮助您。
from typing import NamedTuple,Type
def init_namedtuple(init_func_name):
def wrap(class_obj: Type[NamedTuple]):
def new_instance(*args,**kwargs):
instance_obj = class_obj(*args,**kwargs)
init_func = getattr(instance_obj,init_func_name)
if init_func:
init_func()
return instance_obj
return new_instance
return wrap
@init_namedtuple('init_style')
class TTKStyle(NamedTuple):
...
__插槽__
或者您可以使用普通类并添加__slots__
并将init函数直接放在__init__
上(see class Person3
),例如:
from typing import NamedTuple
class Person(NamedTuple):
NAME: str
SCIENTIFIC_NAME = 'Homo sapiens'
class Person2:
__slots__ = ()
NAME: str
SCIENTIFIC_NAME = 'Homo sapiens'
class Person3:
__slots__ = ()
NAME: str
SCIENTIFIC_NAME = 'Homo sapiens'
def __init__(self,name: str):
self.__class__.NAME = name
...
class Person4:
__slots__ = ('_name','_scientific_name')
def __init__(self,name: str):
self._name = name # Technically,the way is not really read-only,but a conventional is so.
self._scientific_name = 'Homo sapiens'
@property
def name(self):
return self._name
@property
def scientific_name(self):
return self._scientific_name
for person in (Person('Carson'),Person('Carson2')):
print(person.NAME) # output: Carson,Carson2
for person in (Person4('Carson3'),Person4('Carson4')):
print(person.name) # output: Carson3,Carson4
if "it's ok but weird":
unknown_person = Person2()
unknown_person.__class__.NAME = '???'
print(unknown_person.NAME)
for person in [Person3('Marry'),Person3('Marry2')]:
# BE CAREFUL! IF YOU USE THE CLASS ATTRIBUTE,THEN ALL THE INSTANCES IS SHARED THIS VARIABLE.
print(person.NAME) # both output is: Marry2
以上所有属性的类都是只读的(对于2和3,您可以从该类更改它,但不能从实例更改),并且不接受其他新属性。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。