I'm using Python 3.7 and PyCharm 2019.1.3, I've made a subclass of UserString and althought the documentation clearly states I should be able to access the underlying string with myinstance.data PyCharm shows me an Unresolved attribute reference 'data' for class 'Token'.
Here's my subclass:
from collections import UserString
class Token(UserString):
def __init__(self, value, is_emoji: bool):
# if it's not an emoji and a title we lower-case the value
UserString.__init__(self, value.lower() if not is_emoji and value.istitle() else value)
self.is_emoji: bool = is_emoji
if __name__ == '__main__':
token = Token("Sauce", False)
print(token.data)
is it a PyCharm bug or am I doing something wrong ?
Since I can correctly print(token.data) in your example, this indeed must be a bug in PyCharm.
You can try to sidestep it by using super which likely would trigger a different code analysis path and discover the .data member. Did not try it, though.
Related
I am trying to code a class, in python. I think the answer to my question is probably very simple but i am new to code here is the code:
The Actual Code
Once run
I dont see anything wrong, is there something simple i have missed?
the method name and the list name both are actions. when its initialized self.actions ( method) is replaced by self.actions (list). list is not callable
class Troll:
def __init__(self):
self.name = ''
self.phrases = ['Pass the ball','SHOOT']
self.available_actions = ['passes the ball','shoots']
def speak(self):
print(self.name, "shouts", random.choice(self.phrases))
def actions(self):
print(self.name,"decides to", self.available_actions)
In your case method name overrides variable name because both are same. So either change method name or variable name.
I have this code:
from abc import ABCMeta, abstractmethod
class Instruction (object):
__metaclass__ = ABCMeta
def __init__(self, identifier_byte):
#type: (int) ->
self.identifier_byte = identifier_byte
#abstractmethod
def process (self):
print ("Identifier byte: ()".format(self.identifier_byte))
class LDAInstruction (Instruction):
def process (self):
super(Instruction,self).process()
with works fine with Python 3.2 but not with 2.6. Then based on this topic: TypeError: super() takes at least 1 argument (0 given) error is specific to any python version?
I changed the last line to:
super(Instruction,self).process()
which causes this error message on this precise line:
AttributeError: 'super' object has no attribute 'process'
For me it seems that there is a "process" method for the super invocation. Is Python saying that "super" is an independent object, unrelated to instruction? If yes, how can I tell it that super shall only invoke the base class constructor?
If not, how I shall proceed? Thanks for any ideas.
You're passing the wrong class to super in your call. You need to pass the class you're making the call from, not the base class. Change it to this and it should work:
super(LDAInstruction, self).process()
It's unrelated to your main error, but I'd further note that the base-class implementation of process probably has an error with its attempt at string formatting. You probably want {0} instead of () in the format string. In Python 2.7 and later, you could omit the 0, and just use {}, but for Python 2.6 you have to be explicit.
I am trying to override class attribute access in python3. I found this question already answered for python2. But the same is not working with Python3. Please help me to understand why this does not work with Python3 and how to get it to work.
Here is the code i am trying to verify in Python3:
class BooType(type):
def __getattr__(self, attr):
print(attr)
return attr
class Boo(object):
__metaclass__ = BooType
boo = Boo()
Boo.asd #Raises AttributeError in Python3 where as in Python2 this prints 'asd'
from http://python-3-patterns-idioms-test.readthedocs.io/en/latest/Metaprogramming.html
Python 3 changes the metaclass hook. It doesn’t disallow the __metaclass__ field, but it ignores it. Instead, you use a keyword argument in the base-class list:
in your case, you have to change to:
class Boo(object, metaclass = BooType):
pass
and that works. This syntax isn't compatible with python 2, though.
There's a way to create compatible code, seen in http://python-future.org/compatible_idioms.html#metaclasses
# Python 2 and 3:
from six import with_metaclass
# or
from future.utils import with_metaclass
class Boo(with_metaclass(BooType, object)):
pass
I received this warning from PyCharm about an unresolved reference.
Here's code that is structured similarly, and should receive a warning as well.
class Parent:
"""
=== Attributes ===
#type public_attribute_1: str
"""
def __init__(self):
public_attribute_1 = ''
pass
class Child(Parent):
"""
=== Attributes ===
#type public_attribute_1: str
> Unresolved reference 'public_attribute_1'
#type public_attribute_2: str
"""
def __init__(self):
Parent.__init__(self)
public_attribute_2 = ''
pass
I understand that public_attribute_1 is not explicitly initiated in Child.__init__(), but Child.__init__() calls Parent.__init__(self) which initiates public_attribute_1. Thus the error raised concerns readability and documentation more than functionality.
How can I make such code more readable, without inserting redundancies, thereby defeating the whole point of inheritance?
Would it be sufficient to document thoroughly via docstrings and comments, and just ignore the warning from PyCharm? Or is there a pythonic way of doing it?
There are a number of issues here.
In Python 3 use super()
You are calling them "attributes", but this isn't how attributes work in Python. Glossing over details, use self.
Your question seems to be in regards to you want the docstring of Child to have all the attributes of Parent re-defined. This is pretty dangerous from a maintainability perspective though if anything ever changes. When I see a class inherits Parent, if I'm not familiar with Parent, I will go to the definition of Parent (which PyCharm makes easy with Ctrl + B).
I'll let someone else say if that's truly pythonic, but that's the way I'm used to working. Regardless, to fix your inheritance, your code should look more like this:
class Parent:
"""
=== Attributes ===
#type public_attribute_1: str
"""
def __init__(self):
self.public_attribute_1 = ''
class Child(Parent):
"""
=== Attributes ===
#type public_attribute_2: str
"""
def __init__(self):
super().__init__()
self.public_attribute_2 = ''
print(self.public_attribute_1)
In a method of my class MyHeader i access the private property _label of another MyHeader object new_header:
class MyHeader:
def __init__(self, label, n_elem):
self._label = label
self._n_elem = n_elem
def check_header_update(self, new_header):
# check that label is preserved
if new_header._label != self._label:
raise Exception("new header must have the same label")
In PyCharm, this results in the syntax highlighting error "Access to a protected member _label of a class".
I tried specifying the type of the new_header parameter:
def check_header_update(self, new_header: MyHeader):
but this is not recognized, and at run-time this leads to the error "NameError: name 'MyHeader' is not defined".
Any idea how to access the protected member in an accepted way?
The correct way to type your function would be to use forward references, and type your check_header_update like so. Note that I'm also adding the return type, for completeness:
def check_header_update(self, new_header: 'MyHeader') -> None:
The reason why the type needs to be a string is because when you're defining check_header_update, MyHeader hasn't been fully defined yet, so isn't something you can refer to.
However, I don't remember if this will end up fixing the problem or not. If it doesn't, then I would either:
Make _label non-private by removing that underscore
Make some kind of getter method or use properties to let other people access that data
There isn't anything wrong about your initial code sample. It's just that PyCharm doesn't try to guess your parameter type. Most code bases I work with have several thousands warning and even errors from IDE analyses. You can't fix them all.
Anyway, you can specify the type of the parameter through the method docstring and PyCharm won't shout the warning anymore:
class MyHeader:
def __init__(self, label, n_elem):
self._label = label
self._n_elem = n_elem
def check_header_update(self, new_header):
"""
:type new_header: MyHeader
"""
if new_header._label != self._label:
raise Exception("new header must have the same label")
A more modern way to do this is to use type annotation :
def check_header_update(self, new_header : MyHeader):
if new_header._label != self._label:
raise Exception("new header must have the same label")
Though not all IDEs (or all their versions) support it yet.
You can specify complex type hints. See https://docs.python.org/3/library/typing.html for more information.