GVKun编程网logo

Python中类型注释的自引用或前向引用(python 引用类)

18

对于想了解Python中类型注释的自引用或前向引用的读者,本文将提供新的信息,我们将详细介绍python引用类,并且为您提供关于Django模型:两个类之间的相互引用,并且无法在python中使用前向

对于想了解Python中类型注释的自引用或前向引用的读者,本文将提供新的信息,我们将详细介绍python 引用类,并且为您提供关于Django模型:两个类之间的相互引用,并且无法在python中使用前向声明、Java中的非法前向引用、Java子类化问题与泛型类型的自引用类型、Java法律前向引用的有价值信息。

本文目录一览:

Python中类型注释的自引用或前向引用(python 引用类)

Python中类型注释的自引用或前向引用(python 引用类)

我试图弄清楚类型的自引用如何与python3的类型注释一起使用-文档未对此进行任何指定。

举个例子:

from typing import TypeVar, Optional, GenericT = TypeVar(''T'')class Node(Generic[T]):    left = None    right = None    value = None    def __init__(        self, value: Optional[T],        left: Optional[Node[T]]=None,        right: Optional[Node[T]]=None,    ) -> None:        self.value = value        self.left = left        self.right = right

此代码生成错误:

Traceback (most recent call last):  File "node.py", line 4, in <module>    class Node(Generic[T]):  File "node.py", line 12, in Node    right: Optional[Node[T]]=None,NameError: name ''Node'' is not defined

这是使用Python 3.5.1

答案1

小编典典

PEP 0484-类型提示-前向声明的问题解决了以下问题:

类型提示的问题在于,在定义函数时会评估注释(根据PEP
3107,与默认值类似),因此在定义函数时必须已经定义了注释中使用的任何名称。常见的情况是类定义,其方法需要在其注释中引用类本身。(更一般而言,它也可能在相互递归的类中发生。)这对于容器类型是很自然的,例如:

如所写,这是行不通的,因为Python的特殊性是一旦执行了整个类的主体,就定义了类名。
我们的解决方案不是特别优雅,但可以完成工作,它允许在注释中使用字符串文字。 但是,大多数时候您不必使用它-
类型提示的大多数用法都应引用内置类型或其他模块中定义的类型。

from typing import TypeVar, Optional, GenericT = TypeVar(''T'')class Node(Generic[T]):    left = None    right = None    value = None    def __init__(        self,        value: Optional[T],        left: Optional[''Node[T]'']=None,        right: Optional[''Node[T]'']=None,    ) -> None:        self.value = value        self.left = left        self.right = right

>>> import typing>>> typing.get_type_hints(Node.__init__){''return'': None, ''value'': typing.Union[~T, NoneType], ''left'': typing.Union[__main__.Node[~T], NoneType], ''right'': typing.Union[__main__.Node[~T], NoneType]}

Django模型:两个类之间的相互引用,并且无法在python中使用前向声明

Django模型:两个类之间的相互引用,并且无法在python中使用前向声明

我定义了两个模型,每个模型都互相引用,如下所示:

class User(models.Model):    # ...    loves = models.ManyToManyField(Article, related_name=''loved_by'')class Article(models.Model):    # ...    author = models.ForeignKey(User)

您会发现,问题在于两个类都相互引用。无论这两个类的实现顺序如何,python总是会引发NameError异常,抱怨其中一个类都未定义。

答案1

小编典典

您可以在docs中找到解决方案:

如果需要在尚未定义的模型上创建关系,则可以使用模型的名称,而不是模型对象本身:

class Car(models.Model):    manufacturer = models.ForeignKey(''Manufacturer'')    # ...class Manufacturer(models.Model):    # ...

Java中的非法前向引用

Java中的非法前向引用

 import java.io.*; import jxl.*; class Xlparsing {   Workbook wb =wb.getWorkbook(new File(    "C:\\Documents and Settings\\kmoorthi\\Desktop\\ak\\new.xls"));   // Illegal forward reference What it means   Sheet st = wb.getSheet(0);   Cell cell1 = st.getCell(0,0);   String a1 = cell1.getContents();   public static void main(String s[])   {     System.out.println(new Xlparsing().a1);   } }

嗨,当我尝试从excel工作表中提取数据时,文件对象创建中出现了非法的前向引用错误。

如何解决呢?

答案1

小编典典

“非法前向引用”是指您试图在定义变量之前使用它。

在这种情况下,您尝试wb在的声明中调用on的方法wb

Workbook wb = wb.getWorkbook(...);

Java子类化问题与泛型类型的自引用类型

Java子类化问题与泛型类型的自引用类型

import java.util.*;

// Let's define a self-referential type:
class Selfreferential<T extends Selfreferential<T>> {}

//A complete (i.e. not parameterized) subtype of Selfreferential:
class SubclassA extends Selfreferential<SubclassA> {}

//A partial (i.e. parameterized) subtype of Selfreferential:
class SubclassB<T extends SubclassB<T>> extends Selfreferential<T> {}

//Two complete subtypes of SubclassB
class SubclassB1 extends SubclassB<SubclassB1> {}    
class SubclassB2 extends SubclassB<SubclassB2> {}

//Now let's define a generic type over Selfreferential:
class Generic<T extends Selfreferential<T>> {}

//No problem creating a subtype for A,B1 or B2
class GenericA extends Generic<SubclassA> {}   
class GenericB1 extends Generic<SubclassB1> {}    
class GenericB2 extends Generic<SubclassB2> {}

//We can also defined a parameterize type for specific types extending SubclassB
class GenericB<T extends SubclassB<T>> extends Generic<T> {}

//However,it does not seem possible to define a non-parameterized subtype of Generic of ANY subtype of SublassB
//My goal is to provide a type alias for GenericB<? extends SubclassB<?>> to avoid 
//having to mention it everywhere in the code. This is like providing an alias for ArrayList<String> using 
class ArraylistofString extends ArrayList<String> {}

//Unsucessful attempts:
//class GenericAnyB extends Generic<SubclassB> {} //ERROR: bound mismatch
//class GenericAnyB extends Generic<SubclassB<?>> {} //ERROR: bound mismatch
//class GenericAnyB extends Generic<? extends SubclassB<?>> {} //ERROR: invalid Syntax: a supertype cannot specify any wildcard
//class GenericAnyB extends Generic<SubclassB<? extends SubclassB>> {} //ERROR: bound mismatch
//class GenericAnyB extends Generic<SubclassB<SubclassB<SubclassB<SubclassB<SubclassB<SubclassB>>>>>> {} // well...
//class GenericAnyB extends <T extends SubclassB<T>> Generic<T> {} //ERROR: this Syntax is illegal

最重要的是,我无法在extends子句中指定“引用循环”.

问题:这是Java语言限制吗?

解决方法

你是对的,这是不可能的,就像在没有通配符或原始类型的情况下宣布具有自引用类型的变量一样.您将无法直接实例化SubclassB,原因与您在没有自引用类型参数的情况下不能将其用作绑定的原因相同.

有关此限制的更多讨论,请参阅此帖子:Self bound generic type with fluent interface and inheritance

底线是GenericAnyB本身需要通用才能使用SubclassB作为绑定:

class GenericAnyB<T extends SubclassB<T>> extends Generic<T> { }

在任何可用的东西之前,只需在层次结构中添加额外的步骤:

class GenericB1 extends GenericAnyB<SubclassB1> { }   
class GenericB2 extends GenericAnyB<SubclassB2> { }

Java法律前向引用

Java法律前向引用

以下代码是否适用于合法正向引用?如果是,为什么?

public class MyClass
{
  private static int x = getValue();
  private static int y = 5;
  private static int getValue()
  {
    return y;
  }
  public static void main(String[] args)
  {
    System.out.println(x);
  }
}

今天关于Python中类型注释的自引用或前向引用python 引用类的讲解已经结束,谢谢您的阅读,如果想了解更多关于Django模型:两个类之间的相互引用,并且无法在python中使用前向声明、Java中的非法前向引用、Java子类化问题与泛型类型的自引用类型、Java法律前向引用的相关知识,请在本站搜索。

本文标签: