Pycharm 类字段/实例变量的类型提示

问题描述 投票:0回答:3

每当我们在 Java 中需要一个新对象时,我们都会声明类型和名称,选择是否为其赋予初始值。在 Python 中我们不能这样做,因为我们不声明类型。

我怎样才能解决这个问题,因为如果没有声明类型;我没有收到任何代码完成提示。就像特定对象的字段或我们可以在该对象上调用的任何方法一样......

 class Album:
    def __init__(self, name, Photo, next):
        self.name = name
        self.Photo = None
        self.next = next

    def __str__(self):
        return "Album name is: " + self.name


class Photo:
    def __init__(self, name, caption, Tag, next):
        self.name = name
        self.caption = caption
        self.Tag = Tag
        self.next = next

    def __str__(self):
        return "Photo name is: " + self.name + " with caption: " + self.caption


class Tag:
    def __init__(self, type, info, next):
        self.name = type
        self.info = info
        self.next = next

    def __str__(self):
        return "Photo name is: " + self.name


def addPhoto(toEdit, photoName, caption):

   if isinstance(toEdit, Album):    
        if toEdit.Photo is None:
            toEdit.Photo = Photo(photoName, caption, None, None)    
        else:

            tempPhoto = toEdit.Photo
            prev = None
            isFound = False 
            while tempPhoto != None:

                if tempPhoto.name.lower() == photoName.lower():
                    isFound = True
                    break

                prev = tempPhoto
                tempPhoto = tempPhoto.next

            if isFound == False:
                prev.next = Photo(photoName, caption, None, None)

            else:
                print("Photo " + photoName + " already exists in " + toEdit.name)


def deletePhoto(toEdit, photoName): 
    if isinstance(toEdit, Album):
        if photoName in toEdit.Photo.name:
            if toEdit.Photo.next is not None:
                toEdit.Photo = toEdit.Photo.next
                return True

            else:
                toEdit.Photo = None
                return True
        else:
            Photo = toEdit.Photo.next
            Photo_prev = None

            while Photo is not None:
                if Photo.name in photoName:
                    prev.next = Photo.next

                prev = Photo
                Photo = Photo.next

        print("Removed photo: " + photoName + " from " + toEdit.name)

pPtr = album1.Photo  
while (pPtr != None):
    print(pPtr)
    pPtr = pPtr.next

因此,每当我尝试执行

pPtr = album1.Photo
然后尝试访问该
pPtr
对象的任何字段时,我在 PyCharm 中都得不到任何建议。我需要知道我是否做错了或者 PyCharm 是否有问题。

实现是一个巨大的链表。相册节点包含照片节点,照片节点包含标签节点

python pycharm python-typing
3个回答
6
投票

首先,正如您问题的一位评论者指出的那样,使用大写变量名称会将它们与类/类型混淆。如果你看看你的问题,你会发现它甚至混淆了 Stackoverflow 代码格式化程序。

此外,在您的相册构造函数中,您使用本地参数屏蔽全局变量“Photo”。这可能会让 PyCharm 感到困惑,尤其是当您执行以下操作时。因此,对于下面的答案+测试,我将您的参数重命名为小写照片,这样就不会干扰。

**编辑:**我确实找到了更好的方法。请参阅“正确的方法”。

第一次尝试

class Album:
    def __init__(self, name, photo, next):
        self.name = name
        self.photo = self.get_photo(photo)
        self.next = next

    def get_photo(self, photo):
        """
        @rtype: Photo
        """
        return photo

    def __str__(self):
        return "Album name is: " + self.name

它的工作方式是使用 PyCharm 类型推断。有关其工作原理的详细信息,请参阅此处

下面是它的工作截图:

Image of answer working

注意:我不建议这样做,因为这是一种黑客行为。我遇到你的问题是因为我试图找出 PyCharm 中是否有更好的方法来做到这一点。

正确的方法

正确的方法是在构造函数中为 PyCharm 提供变量的类型。本质上,将类型绑定从上面的方法移动到构造函数中,作为文档字符串条目“type”的一部分。

class Album:
    def __init__(self, name, photo, next):
        """
        @type name: str
        @type photo: Photo
        @type next: str
        """
        self.name = name
        self.photo = photo
        self.next = next

    def __str__(self):
        return "Album name is: " + self.name


class Photo:
    def __init__(self, name, caption, Tag, next):
        self.name = name
        self.caption = caption
        self.Tag = Tag
        self.next = next

photo1 = Photo("name.txt", "caption", "tag", "next")

album1 = Album("TestAlbum", photo1, "next")

album1.photo.#code completion working here

0
投票

这是动态类型语言的限制。 类型的静态分析只能在某种程度上进行。 因此,不要期望像静态类型语言那样有那么多的自动完成功能。


0
投票

您应该遵循此处的 intellij 程序:

https://www.jetbrains.com/help/pycharm/type-hinting-in-product.html

示例:

class SomeClass(object):
    __logger = None  # type: Logger

 def __init__(self):
     self.__logger = logging.getLogger('root')

def some_method:
    self.__logger.info('hint completion is working here :P')
© www.soinside.com 2019 - 2024. All rights reserved.