鱼C论坛

 找回密码
 立即注册
查看: 2219|回复: 4

[已解决]求助 node_names: List[str] | None = None 具体的意思

[复制链接]
发表于 2022-10-19 13:39:37 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
请教各位大佬这个代码 node_names: List[str] | None = None 一直不知道什么意思,查阅后发现解释各种各样,想问问List[str] 是list和str转换的意思吗? | None = None 也不是很明白。以及这个定义的CausalGraph这个类 实例化后是不是就是直接命名no_of_var=???这样呢

class CausalGraph:
    def __init__(self, no_of_var: int, node_names: List[str] | None = None):
        if node_names is None:
            node_names = [("X%d" % (i + 1)) for i in range(no_of_var)]
        assert len(node_names) == no_of_var, "number of node_names must match number of variables"
        assert len(node_names) == len(set(node_names)), "node_names must be unique"
        nodes: List[Node] = []
        for name in node_names:
            node = GraphNode(name)
            nodes.append(node)
        self.G: GeneralGraph = GeneralGraph(nodes)
        for i in range(no_of_var):
            for j in range(i + 1, no_of_var):
                self.G.add_edge(Edge(nodes[i], nodes[j], Endpoint.TAIL, Endpoint.TAIL))
        self.test: CIT | None = None
        self.sepset = np.empty((no_of_var, no_of_var), object)  # store the collection of sepsets
        self.definite_UC = []  # store the list of definite unshielded colliders
        self.definite_non_UC = []  # store the list of definite unshielded non-colliders
        self.PC_elapsed = -1  # store the elapsed time of running PC
        self.redundant_nodes = []  # store the list of redundant nodes (for subgraphs)
        self.nx_graph = nx.DiGraph()  # store the directed graph
        self.nx_skel = nx.Graph()  # store the undirected graph
        self.labels = {}
        self.prt_m = {}  # store the parents of missingness indicators


最佳答案
2022-10-19 16:04:56
node_names: List[str] | None = None

其中的node_names是参数名,冒号后面的部分叫做“类型注释”或者“类型注解”,用来说明期望传入的参数类型

List[str]表示列表类型,其中的元素都是字符串类型,又称元素为字符串的列表类型;
“|”这个符号叫做管道符号,此处表示“或者”的意思。注意此处的语法高版本(Python 3.10及以上)才支持,低版本一般用Union表示,例如Union[int, float, complex]意思是说参数可以是int、float或者complex类型。

所以node_names: List[str] | None的意思是说node_names的类型可以是元素为字符串的列表类型也可以是NoneType类型(None是NoneType类型的唯一值)。

至于最后的=None表示node_names这个参数的默认值为None。

特别注意:类型注释不是强制的,加上类型注释可以明确告知调用方需要传入何种类型的值从而避免类型不一致引发的异常。由于类型注释不是强制的,所以简化后的__init__函数是这样的:
def __init__(self, no_of_var, node_names=None):
    ...

最后
以及这个定义的CausalGraph这个类 实例化后是不是就是直接命名no_of_var=???这样呢
这句话我不是很理解, 所以暂时无法给你更进一步的解答
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-10-19 16:04:56 | 显示全部楼层    本楼为最佳答案   
node_names: List[str] | None = None

其中的node_names是参数名,冒号后面的部分叫做“类型注释”或者“类型注解”,用来说明期望传入的参数类型

List[str]表示列表类型,其中的元素都是字符串类型,又称元素为字符串的列表类型;
“|”这个符号叫做管道符号,此处表示“或者”的意思。注意此处的语法高版本(Python 3.10及以上)才支持,低版本一般用Union表示,例如Union[int, float, complex]意思是说参数可以是int、float或者complex类型。

所以node_names: List[str] | None的意思是说node_names的类型可以是元素为字符串的列表类型也可以是NoneType类型(None是NoneType类型的唯一值)。

至于最后的=None表示node_names这个参数的默认值为None。

特别注意:类型注释不是强制的,加上类型注释可以明确告知调用方需要传入何种类型的值从而避免类型不一致引发的异常。由于类型注释不是强制的,所以简化后的__init__函数是这样的:
def __init__(self, no_of_var, node_names=None):
    ...

最后
以及这个定义的CausalGraph这个类 实例化后是不是就是直接命名no_of_var=???这样呢
这句话我不是很理解, 所以暂时无法给你更进一步的解答
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-10-19 17:15:52 | 显示全部楼层
Brick_Porter 发表于 2022-10-19 16:04
其中的node_names是参数名,冒号后面的部分叫做“类型注释”或者“类型注解”,用来说明期望传入的参数类 ...

非常感谢大佬的解答,都理解了!
no_of_var: int这块的意思是变量的个数,一般都是整数,我想问一下,实例化是怎么输入呢?是直接把no_of_var 替换成整数?还是要设定a=self.no_of_var()这样的形式?

也想追问一下:
if node_names is None:
node_names = [("X%d" % (i + 1)) for i in range(no_of_var)]
这里是在node_names=None的基础上添加node_names吗?也相当于if node_names=[]:
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-10-19 19:24:20 | 显示全部楼层
小豆豆子 发表于 2022-10-19 17:15
非常感谢大佬的解答,都理解了!
no_of_var: int这块的意思是变量的个数,一般都是整数,我想问一下,实 ...

分别回答你的两个问题。

第一个问题:“实例化”这个词是针对类来说的,创建某个类型的实例叫做“实例化”。对于你的代码来说就是要实例化CausalGraph这个类。我们可以看到,这个类的no_of_var这个参数是没有默认值的,也就是说必须给它传值才能成功实例化一个CausalGraph对象,同时我们通过no_of_var的类型注释可以判断应该传给它一个整数,那就简单了:
cg1 = CausalGraph(15)
cg2 = CausalGraph(no_of_var=233)
以上两种写法均可。

第二个问题的答案是肯定的,但也不是完全和你的理解一致。根据条件判断语句 if node_names is None 可以判断出来,确实如你所想,当node_names=None也就是它的值是默认值None的时候才会执行接下来的列表生成式语句。

不过 if node_names is None 和 if node_names== [] (你漏掉了一个等号,不过这不是我要说的重点)不相等!条件判断时Python默认会把None、[]、set()、{}、()、空字符串都视为False,不过如果真的要判断是否为空值,最好使用 xxx is None 或者 xxx is not None 这样的形式。

以你提供的代码为例,既然空字符串、空列表、空集合、空字典都可以视为False,那么只把node_names的值和空列表进行判断是有潜在隐患的。前面已经解释过了,None是NoneTyple类型下的唯一值,所以对于你的代码来说node_names的值就只有None和非None两种情况了,由于排除了其他的可能性,所以即使程序运行出错你也可以很快判断到底是用户传入的参数不对还是自己考虑不周导致有逻辑漏洞。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-10-19 20:46:48 | 显示全部楼层
Brick_Porter 发表于 2022-10-19 19:24
分别回答你的两个问题。

第一个问题:“实例化”这个词是针对类来说的,创建某个类型的实例叫做“实例 ...

非常感谢大佬的解答 这一部分已经完全理解了!!!非常感谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-26 01:25

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表