Can an object be set to None when initialized, but still belong to a class?
class Foo:
def do_stuff():
pass
bar_1 = Foo()
bar_2 = None
The specific purpose I have in mind is that I want bar_2 to be available accross different modules, but define it at a later date (for reasons that are irrelevant). It works just fine, when you run the code. My IDE, however, does not know that bar_2 is of type Foo, and hence will not show me do_stuff() as an autocomplete option the way it does for bar_1, for instance.
I understand that python is not a strongly typed language, but I reckon if there was a way to tell python that bar_2 is of type Foo, it would solve the problem of autocomplete not showing up.
If there is another way to make my IDE (PyCharm, specifically) aware of bar_2's class, I'd be happy to know.
If you're using Python 3.5, you can use type hinting. For this specific use, you'd need to put it in a type comment:
bar_2 = None # type: Foo
Earlier versions of Python don't have a builtin way of doing this, though I suppose an IDE that supports both earlier and later versions of the language might allow type comments to effect it's behavior even if the Python version you're using doesn't support the full type hinting semantics.
Try using type hints assuming the type is consistent and you're using python 3.5.
To get the intellisense completion JetBrains has a legacy type hinting system that should work for all versions of python.
when it is supposed to be an instance of foo you can do
assert isinstance(bar_2,Foo)
# anything below this and in scope will autocomplete bar_2 with Foo's methods
In general this is not a very good practice, and should be avoided but it works to enable autocomplete in most IDE's (pycharm included)
Related
I'm currently developing a dynamic software system in python. It includes the use of dependency injection at many points, which is implemented with dynamic class attributes. My aim is to add a function dynamically to a class (with setattr) an this works quite fine. The only problem I have is that the IDE (in my case it's PyCharm) has no idea about those functions and marks it as "unresolved reference". Although the script runs without errors, it looks not very nice and I want the IDE to support other programmers, that don't know about those functions.
Here is an example of what I mean:
class A:
def __init__(self, func_obj):
setattr(self, 'custom_function', func_obj)
a = A(print) # Unresolved attribute reference 'custom_function' for class 'A' ...
a.custom_function('Hello World!')
As expected, this example prints "Hello World!". But I find it's ugly, that the IDE shows a warning for the last line, where I called "custom_function". And also there is no auto completion if you try to explore the script with duck typing.
So let me come to my question: Is there any way to tell the IDE that there are some dynamically added functions in this class? Maybe there is some way with meta classes or something like that... But I didn't find anything on Google and I have no idea where else to try.
I hope you can help me with that :)
I had a similar request and asked directly to PyCharm bug tracker: PY-28326. I think that their answer applies to your question too:
PyCharm at the moment doesn't support methods dynamically added to classes.
I'm using PyCharm for python coding. The autocompletion in PyCharm is not as good as in IntelliJ (Java). Consider the below code
a = [1,2,3,4]
a.
In this case, after I press the dot, PyCharm gives the full set of autocompletion options. Consider the below case
def func_a(a):
a.
Here, to the function func_a I'm passing a list as an argument. But when I press dot after a, PyCharm doesn't give any autocompletion options. I know this is because Python is dynamically typed language and PyCharm has no idea to determine what type a is.
But is there any way to tell PyCharm the type of a, may be in documentation comment or something like that? So, that PyCharm can give valid autocompletion options?
Yes, Python 3.5 introduces type hinting and Pycharm utilizes that.
Use
def func_name(param: type) -> return_type:
Like
def func_a(a: list):
Note that all type hints are completely optional and ignored by the interpreter. However, Pycharm can potentially help you detect type errors if you use it as a habit.
This might not answer your question but this will be helpful for those who just started using pycharm for Django application.
PyCharm does not give (It underlines some built in functions with red) auto-completion option for Django if you have started project with Pure Python. Pure Python option comes when you click on new project option from file menu or when you run pycharm to start new project. Pure Python is the default selected option on new project page. You should choose Django (the 2nd option) to get auto-completion option in PyCharm.
Hope this would be helpful for others.
Can do : (examples using list):
def func_a(a:list):
do_this()
Or manually check:
def func_a(a):
if isinstance(a,list):
do_this
else:
raise TypeError("expected type of 'list' but got type of '%s'"%type(a).__name__)
I found out that Python is intending to support static typing, but it still in beta phase.
I tried the following code with python 3.4.3:
def somme(a: int, b: int) -> int:
return a + b
the syntax is supported but I did not get the expected result. if I type somme('1', '3') I get 13, while I should get TypeError exception saying int variable expected.
Has anyone an idea why it's not working ?
The function annotations there are annotations, nothing more. They're documentation about intended usage. Like it says in PEP 3107, the mechanism provides a single, standard way to specify function parameters and return values, replacing a variety of ad-hoc tools and libraries.
But as it goes on to say:
Function annotations are nothing more than a way of associating
arbitrary Python expressions with various parts of a function at
compile-time.
By itself, Python does not attach any particular meaning or
significance to annotations. Left to its own, Python simply makes
these expressions available as described in Accessing Function
Annotations below.
PEP 484 adds more conventions and tools for using these annotations to mark types, adopted in Python 3.5. But still there is no runtime checking in the language itself: it "includes support for off-line type checkers such as mypy".
That is, after using these annotations, you can run third-party type checkers to check if your code adheres to the annotated types. Building these annotations into the language should make it easier for various IDEs to provide this service.
In reality, you aren't supposed to get static typing here. The code you wrote is actually a form of easy documentation and "type hinting", as explained here. To quote that PEP:
While these annotations are available at runtime through the usual annotations attribute, no type checking happens at runtime . Instead, the proposal assumes the existence of a separate off-line type checker which users can run over their source code voluntarily. Essentially, such a type checker acts as a very powerful linter. (While it would of course be possible for individual users to employ a similar checker at run time for Design By Contract enforcement or JIT optimization, those tools are not yet as mature.)
So in other words, it was developed to support a third party library that will actually do the checking for you. I've never bothered with static typing in Python, although a friend of mine often uses MyPy to achieve it. This might be what you're looking for.
EDIT:
installation : MyPy can be installed using pip:
pip install mypy-lang
Usage : you can type-check your program as follow:
~$ mypy my_script.py
I'd like to say something like:
'''#type foo: list<Bar>'''
and then have it know that when I access an element of foo, the resulting value is of type Bar.
Unfortunately PyDev still does not support that... (this is a shortcoming on PyDev itself and it's already reported: see: https://sw-brainwy.rhcloud.com/tracker/PyDev/147)
Once the basic type inference can work with it, then type-hinting should have that support enable too...
Two years later: the correct answer is now to use Python's type annotations and MyPy :)
I am using eclipse for python and I am facing a problem. I have many classes with many properties and want a list of objects from one of my declared classes. The problem is: When I am accessing any item from the list, the IDE does not know its type because in python we do not declare the variable with type, so there is no auto complete and I have to go to the class to copy the attribute name.
To make idea more clear:
class AutomataBranch(object):
def __init__(selfparams):
self.Name="";
self.nodes=[];
class LanguageAutomata(object):
def __init__(selfparams):
self.cfgAutomata=[];#This has AutomaBranch Type
Now in any method in LanguageAutomata class if I wrote:
cfgAutomata. Then it wont give me the Name attribute
Is there any solution for that?
Python is strongly typed and Python lists are too. Your problem come from the fact that Python is dynamically typed. Therefor a var can contain any type, and therefor no IDE can guess what is the type of your parameter, nor give you code completion for the methods.
This is how it is, there is no clean workaround. If it's a problem, then maybe dynamics language is not you predilection tool and you should use something that fit your development style. There are tools for everybody.
8 years later and we actually have a solution in Python 3.6.
PEP484 allows you to annotate your variables primarily for IDEs and linting:
Modifying #Hani's answer:
x : AutomataBranch = self.cfgAutomata[i]
This is now picked up by any good IDE to highlight errors and allow autocomplete.
I think you mean to say "statically typed" instead of "strongly typed." Python is strongly typed. You just don't know what that type is at compile time.
With that said, you really need to abandon the idea that you're going to find any IDEs that work as well for Python as they do for Java or C#. Python's dynamic typing makes this difficult. In fact, I tend to find that powerful IDEs are more of a burden than a help.
I think I found a good managable solution. Actually it is trivial but may help (I used it now).
When I want to access the list then I assign the object which I want to access to a variable ex:
x = AutomataBranch()
x = self.cfgAutomata[i]
The first line is used only to make the IDE knows that x is from AutomatBranch type. After that when I press x then all methods and properties are visualized.
I think it is some how good.