itcl读属性是什么?
Itcl What is the read property?
我想控制对 Itcl public 变量的读取访问。我可以使用诸如
之类的东西来执行此操作以进行写访问
package require Itcl
itcl::class base_model_lib {
public variable filename ""
}
itcl::configbody base_model_lib::filename {
puts "in filename write"
dict set d_model filename $filename
}
configbody 定义调用 config 时发生的情况:$obj configure -filename foo.txt
。但是我如何控制读取过程中发生的事情呢?想象一下,我想做的不仅仅是在读取过程中查找一个值。
我想继续使用标准的 Itcl 模式,即使用 cget/configure 向用户公开这些内容。
这就是我的问题。但是,让我描述一下我真正想做的事情,你告诉我是否应该做一些完全不同的事情:)
我喜欢python类。我喜欢我可以从实例外部创建一个变量并 read/write 到它。稍后,当我想变得有趣时,我将创建方法(使用 @property
和 @property.setter
)来自定义 read/write 而用户不会看到 API 更改。我正在尝试在这里做同样的事情。
我的示例代码还提出了我想做的其他事情。实际上,文件名内部存储在字典中。我不想向用户公开整个字典,但我确实希望他们能够更改该字典中的值。所以,实际上 'filename' 只是一个存根。我不想要一个叫那个的 public 变量。相反,我想使用 cget 和配置来读写 "thing",我可能会选择创建一个简单的 public 变量,或者可能希望定义一个查找它的过程。
PS:我确定我可以创建一个接受一个或两个参数的方法。如果一个,它是一个读取,两个是一个写入。我认为这不是正确的方法,因为 我不认为 你可以使用 cget/configure 方法。
所有 Itcl 变量都映射到名称难以猜测的命名空间中的 Tcl 变量。这意味着无论何时通过 Tcl 的标准跟踪机制读取变量(它发生在实际读取变量之前),您都可以获得回调;您需要做的就是create the trace in the constructor。这需要使用 itcl::scope
并且最好使用 itcl::code $this
来完成,这样我们就可以使回调成为私有方法:
package require Itcl
itcl::class base_model_lib {
public variable filename ""
constructor {} {
trace add variable [itcl::scope filename] read [itcl::code $this readcallback]
}
private method readcallback {args} { # You can ignore the arguments here
puts "about to read the -filename"
set filename "abc.[expr rand()]"
}
}
所有 itcl::configbody
所做的实际上等同于变量写入跟踪,这更常见一些,但现在我们通常更希望您直接设置跟踪,因为这是一种更通用的机制。在 运行 之后演示上面的脚本:
% base_model_lib foo
foo
% foo configure
about to read the -filename
{-filename {} abc.0.8870089169996832}
% foo configure -filename
about to read the -filename
-filename {} abc.0.9588680136757288
% foo cget -filename
about to read the -filename
abc.0.694705847974264
如您所见,我们正在通过标准机制精确控制读取的内容(在本例中,是一些随机变化的乱码,但您可以做得更好)。
我想控制对 Itcl public 变量的读取访问。我可以使用诸如
之类的东西来执行此操作以进行写访问package require Itcl
itcl::class base_model_lib {
public variable filename ""
}
itcl::configbody base_model_lib::filename {
puts "in filename write"
dict set d_model filename $filename
}
configbody 定义调用 config 时发生的情况:$obj configure -filename foo.txt
。但是我如何控制读取过程中发生的事情呢?想象一下,我想做的不仅仅是在读取过程中查找一个值。
我想继续使用标准的 Itcl 模式,即使用 cget/configure 向用户公开这些内容。
这就是我的问题。但是,让我描述一下我真正想做的事情,你告诉我是否应该做一些完全不同的事情:)
我喜欢python类。我喜欢我可以从实例外部创建一个变量并 read/write 到它。稍后,当我想变得有趣时,我将创建方法(使用 @property
和 @property.setter
)来自定义 read/write 而用户不会看到 API 更改。我正在尝试在这里做同样的事情。
我的示例代码还提出了我想做的其他事情。实际上,文件名内部存储在字典中。我不想向用户公开整个字典,但我确实希望他们能够更改该字典中的值。所以,实际上 'filename' 只是一个存根。我不想要一个叫那个的 public 变量。相反,我想使用 cget 和配置来读写 "thing",我可能会选择创建一个简单的 public 变量,或者可能希望定义一个查找它的过程。
PS:我确定我可以创建一个接受一个或两个参数的方法。如果一个,它是一个读取,两个是一个写入。我认为这不是正确的方法,因为 我不认为 你可以使用 cget/configure 方法。
所有 Itcl 变量都映射到名称难以猜测的命名空间中的 Tcl 变量。这意味着无论何时通过 Tcl 的标准跟踪机制读取变量(它发生在实际读取变量之前),您都可以获得回调;您需要做的就是create the trace in the constructor。这需要使用 itcl::scope
并且最好使用 itcl::code $this
来完成,这样我们就可以使回调成为私有方法:
package require Itcl
itcl::class base_model_lib {
public variable filename ""
constructor {} {
trace add variable [itcl::scope filename] read [itcl::code $this readcallback]
}
private method readcallback {args} { # You can ignore the arguments here
puts "about to read the -filename"
set filename "abc.[expr rand()]"
}
}
所有 itcl::configbody
所做的实际上等同于变量写入跟踪,这更常见一些,但现在我们通常更希望您直接设置跟踪,因为这是一种更通用的机制。在 运行 之后演示上面的脚本:
% base_model_lib foo
foo
% foo configure
about to read the -filename
{-filename {} abc.0.8870089169996832}
% foo configure -filename
about to read the -filename
-filename {} abc.0.9588680136757288
% foo cget -filename
about to read the -filename
abc.0.694705847974264
如您所见,我们正在通过标准机制精确控制读取的内容(在本例中,是一些随机变化的乱码,但您可以做得更好)。