Reputation: 163
Whenever we need a new object in Java, we declare the type and the name choose to give it a initial value or not. In Python we can't do this, because we don't declare types.
How can I get around this because if the types are not declared; I am not getting any code completion hints. Like the fields of a particular object or any methods we can call on the object...
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
So whenever I try to do pPtr = album1.Photo
and then try to access any fields of that pPtr
object I get no suggestions in PyCharm. I need to know whether I am doing this wrong or if PyCharm is at fault.
The implementation is one giant linkedlists. Albums nodes contain Photo nodes which contain Tag nodes
Upvotes: 6
Views: 3732
Reputation: 136
You should follow the intellij procedure here:
https://www.jetbrains.com/help/pycharm/type-hinting-in-product.html
Example:
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')
Upvotes: 0
Reputation: 1232
First off, as one of the commenters on your question pointed out, using upper_case variable names confuses them with Classes/Types. If you look at your question, you'll see it even confused the Stackoverflow code-formatter.
Additionally, in your Album constructor, you are masking the global variable "Photo" with a local parameter. That might confuse PyCharm, especially when you do the following. So for my answer + test below, I renamed your parameter to a lower-case photo so that it doesn't interfere.
**Edit: ** I did find a better way. See "The Right Way".
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
The way it works is it uses the PyCharm type-inference. See here for details on how it works.
And below a screenshot of it working:
Note: I do not recommmend doing this, as it is a hack. I came across your question as I'm attempting to find out if there is a better way of doing this in PyCharm.
The right way of doing this is to give PyCharm the type of the variables in the constructor. Essentially, moving the type-binding from the method as above, and into the constructor as part of the docstring entry "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
Upvotes: 6
Reputation: 4679
It is a limitation of dynamically typed languages. Static analysis of types is only possible to some degree. So don't expect as much autocompletion as in statically typed languages.
Upvotes: 0