classPerson:def __init__(self, name, age):
self.name = name
self.age = age
peasant =Person("Dennis",37)# PyCharm knows that the "peasant" variable is of type Person
peasant.dig_filth()# shows warning -- Person doesn't have a dig_filth methodclassKing:def repress(self, peasant):# PyCharm has no idea what type the "peasant" parameter should be
peasant.knock_over()# no warning even though knock_over doesn't existKing().repress(peasant)# Even if I call the method once with a Person instance, PyCharm doesn't# consider that to mean that the "peasant" parameter should always be a Person
classKing:def repress(self, peasant):"""
Exploit the workers by hanging on to outdated imperialist dogma which
perpetuates the economic and social differences in our society.
@type peasant: Person
@param peasant: Person to repress.
"""
peasant.knock_over()# Shows a warning. And there was much rejoicing.
When it comes to constructors, and assignments, and method calls, the PyCharm IDE is pretty good at analyzing my source code and figuring out what type each variable should be. I like it when it’s right, because it gives me good code-completion and parameter info, and it gives me warnings if I try to access an attribute that doesn’t exist.
But when it comes to parameters, it knows nothing. The code-completion dropdowns can’t show anything, because they don’t know what type the parameter will be. The code analysis can’t look for warnings.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
peasant = Person("Dennis", 37)
# PyCharm knows that the "peasant" variable is of type Person
peasant.dig_filth() # shows warning -- Person doesn't have a dig_filth method
class King:
def repress(self, peasant):
# PyCharm has no idea what type the "peasant" parameter should be
peasant.knock_over() # no warning even though knock_over doesn't exist
King().repress(peasant)
# Even if I call the method once with a Person instance, PyCharm doesn't
# consider that to mean that the "peasant" parameter should always be a Person
This makes a certain amount of sense. Other call sites could pass anything for that parameter. But if my method expects a parameter to be of type, say, pygame.Surface, I’d like to be able to indicate that to PyCharm somehow, so it can show me all of Surface‘s attributes in its code-completion dropdown, and highlight warnings if I call the wrong method, and so on.
Is there a way I can give PyCharm a hint, and say “psst, this parameter is supposed to be of type X”? (Or perhaps, in the spirit of dynamic languages, “this parameter is supposed to quack like an X”? I’d be fine with that.)
EDIT: CrazyCoder’s answer, below, does the trick. For any newcomers like me who want the quick summary, here it is:
class King:
def repress(self, peasant):
"""
Exploit the workers by hanging on to outdated imperialist dogma which
perpetuates the economic and social differences in our society.
@type peasant: Person
@param peasant: Person to repress.
"""
peasant.knock_over() # Shows a warning. And there was much rejoicing.
The relevant part is the @type peasant: Person line of the docstring.
If you also go to File > Settings > Python Integrated Tools and set “Docstring format” to “Epytext”, then PyCharm’s View > Quick Documentation Lookup will pretty-print the parameter information instead of just printing all the @-lines as-is.
Yes, you can use special documentation format for methods and their parameters so that PyCharm can know the type. Recent PyCharm version supports most common doc formats.
classKing:def repress(self, peasant:Person)-> bool:
peasant.knock_over()# Shows a warning. And there was much rejoicing.return peasant.badly_hurt()# Lets say, its not known from here that this method will always return a bool
If you are using Python 3.0 or later, you can also use annotations on functions and parameters. PyCharm will interpret these as the type the arguments or return values are expected to have:
class King:
def repress(self, peasant: Person) -> bool:
peasant.knock_over() # Shows a warning. And there was much rejoicing.
return peasant.badly_hurt() # Lets say, its not known from here that this method will always return a bool
Sometimes this is useful for non-public methods, that do not need a docstring. As an added benefit, those annotations can be accessed by code:
Update: As of PEP 484, which has been accepted for Python 3.5, it is also the official convention to specify argument and return types using annotations.
classKing:def repress(self, peasant):"""
Exploit the workers by hanging on to outdated imperialist dogma which
perpetuates the economic and social differences in our society.
@type peasant: Person
@param peasant: Person to repress.
"""
peasant.knock_over()# Shows a warning. And there was much rejoicing.
PyCharm extracts types from a @type pydoc string. See PyCharm docs here and here, and Epydoc docs. It’s in the ‘legacy’ section of PyCharm, perhaps it lacks some functionality.
class King:
def repress(self, peasant):
"""
Exploit the workers by hanging on to outdated imperialist dogma which
perpetuates the economic and social differences in our society.
@type peasant: Person
@param peasant: Person to repress.
"""
peasant.knock_over() # Shows a warning. And there was much rejoicing.
The relevant part is the @type peasant: Person line of the docstring.
My intention is not to steal points from CrazyCoder or the original questioner, by all means give them their points. I just thought the simple answer should be in an ‘answer’ slot.
回答 3
我正在使用PyCharm Professional 2016.1编写py2.6-2.7代码,发现使用reStructuredText可以以更简洁的方式表达类型:
classReplicant(object):passclassHunter(object):def retire(self, replicant):""" Retire the rogue or non-functional replicant.
:param Replicant replicant: the replicant to retire.
"""
replicant.knock_over()# Shows a warning.
I’m using PyCharm Professional 2016.1 writing py2.6-2.7 code, and I found that using reStructuredText I can express types in a more succint way:
class Replicant(object):
pass
class Hunter(object):
def retire(self, replicant):
""" Retire the rogue or non-functional replicant.
:param Replicant replicant: the replicant to retire.
"""
replicant.knock_over() # Shows a warning.
Is there a way to configure PyCharm to be able to surround selected code with parenthesis by just typing on the parenthesis key, like when we use SublimText 2?
回答 0
我想你想要类似的东西
Settings | Editor | General | Smart Keys -> Surround selection on typing quote or brace
Windows: open pycharm and select file, settings, Editor, Smart Keys, in the list you will check “Surround selection on typing quote or brace”, then apply.
enter image description here
I am trying to plot a simple graph using pyplot, e.g.:
import matplotlib.pyplot as plt
plt.plot([1,2,3],[5,7,4])
plt.show()
but the figure does not appear and I get the following message:
UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure.
I saw in several places that one had to change the configuration of matplotlib using the following:
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
I did this, but then got an error message because it cannot find a module:
ModuleNotFoundError: No module named 'tkinter'
Then, I tried to install “tkinter” using pip install tkinter (inside the virtual environment), but it does not find it:
Collecting tkinter
Could not find a version that satisfies the requirement tkinter (from versions: )
No matching distribution found for tkinter
I should also mention that I am running all this on Pycharm Community Edition IDE using a virtual environment, and that my operating system is Linux/Ubuntu 18.04.
I would like to know how I can solve this problem in order to be able to display the graph.
In my case, the error message was implying that I was working in a headless console. So plt.show() could not work. What worked was calling plt.savefig:
import matplotlib.pyplot as plt
plt.plot([1,2,3], [5,7,4])
plt.savefig("mygraph.png")
I’ve tried your way, it seems no error to run at my computer, it successfully shows the figure. maybe because pycharm have tkinter as a system package, so u don’t need to install it. But if u can’t find tkinter inside, you can go to Tkdocs to see the way of installing tkinter, as it mentions, tkinter is a core package for python.
After upgrading lots of packages (Spyder 3 to 4, Keras and Tensorflow and lots of their dependencies), I had the same problem today! I cannot figure out what happened; but the (conda-based) virtual environment that kept using Spyder 3 did not have the problem. Although installing tkinter or changing the backend, via matplotlib.use('TkAgg) as shown above, or this nice post on how to change the backend, might well resolve the problem, I don’t see these as rigid solutions. For me, uninstalling matplotlib and reinstalling it was magic and the problem was solved.
pip uninstall matplotlib
… then, install
pip install matplotlib
From all the above, this could be a package management problem, and BTW, I use both conda and pip, whenever feasible.
When I ran into this error on Spyder, I changed from running my code line by line to highlighting my block of plotting code and running that all at once. Voila, the image appeared.
tkinter is python version-specific in the sense that sudo apt-get install python3-tk will install tkinter exclusively for your default version of python. Suppose you have different python versions within various virtual environments, you will have to install tkinter for the desired python version used in that virtual environment. For example, sudo apt-get install python3.7-tk. Not doing this will still lead to No module named ' tkinter' errors, even after installing it for the global python version.
I think you are saying that you have python2 and python3 installed and have added a reference to each version under Pycharm > Settings > Project Interpreter
What I think you are asking is how do you have some projects run with Python 2 and some projects running with Python 3.
If so, you can look under Run > Edit Configurations
There is a new feature called Interpreter in status bar (scroll down a little bit). This makes switching between python interpreters and seeing which version you’re using easier.
Enable status bar
In case you cannot see the status bar, you can easily activate it by running the Find Action command (Ctrl+Shift+A or ⌘+ ⇧+A on mac). Then type status bar and choose View: Status Bar to see it.
This can also happen in Intellij Ultimate, which has PyCharm integrated. The issue is as diagnosed above, you have the wrong interpreter selected.
The exact method to fix this for any given project is to go to Project Settings…Project and adjust the Project SDK. You can add a New Project SDK if you don’t have Python 3 added by navigating to the python3 binary. This will fix the errors listed above. A shortcut to Project Settings is the blue checkerboard-type icon.
You can also add Python 3 as the default interpreter for Python projects. On OSX this is in File..Other Settings…Default Project Structure. There you can set the Project SDK which will now apply on each new project. It can be different on other platforms, but still similar.
I am working on Scrapy 0.20 with Python 2.7. I found PyCharm has a good Python debugger. I want to test my Scrapy spiders using it. Anyone knows how to do that please?
What I have tried
Actually I tried to run the spider as a script. As a result, I built that script. Then, I tried to add my Scrapy project to PyCharm as a model like this:
The scrapy command is a python script which means you can start it from inside PyCharm.
When you examine the scrapy binary (which scrapy) you will notice that this is actually a python script:
#!/usr/bin/python
from scrapy.cmdline import execute
execute()
This means that a command like
scrapy crawl IcecatCrawler can also be executed like this: python /Library/Python/2.7/site-packages/scrapy/cmdline.py crawl IcecatCrawler
Try to find the scrapy.cmdline package.
In my case the location was here: /Library/Python/2.7/site-packages/scrapy/cmdline.py
Create a run/debug configuration inside PyCharm with that script as script. Fill the script parameters with the scrapy command and spider. In this case crawl IcecatCrawler.
Like this:
Put your breakpoints anywhere in your crawling code and it should work™.
回答 1
您只需要这样做。
在项目的搜寻器文件夹上创建一个Python文件。我使用了main.py。
项目
履带式
履带式
蜘蛛网
…
main.py
scrapy.cfg
在您的main.py内部,将下面的代码。
from scrapy import cmdline
cmdline.execute("scrapy crawl spider".split())
As of 2018.1 this became a lot easier. You can now select Module name in your project’s Run/Debug Configuration. Set this to scrapy.cmdline and the Working directory to the root dir of the scrapy project (the one with settings.py in it).
I am running scrapy in a virtualenv with Python 3.5.0 and setting the “script” parameter to /path_to_project_env/env/bin/scrapy solved the issue for me.
回答 4
intellij的想法也可以。
创建main.py:
#!/usr/bin/env python# -*- coding: utf-8 -*-#coding=utf-8import sys
from scrapy import cmdline
def main(name):if name:
cmdline.execute(name.split())if __name__ =='__main__':print('[*] beginning main thread')
name ="scrapy crawl stack"#name = "scrapy crawl spa"
main(name)print('[*] main thread exited')print('main stop====================================================')
To add a bit to the accepted answer, after almost an hour I found I had to select the correct Run Configuration from the dropdown list (near the center of the icon toolbar), then click the Debug button in order to get it to work. Hope this helps!
I am also using PyCharm, but I am not using its built-in debugging features.
For debugging I am using ipdb. I set up a keyboard shortcut to insert import ipdb; ipdb.set_trace() on any line I want the break point to happen.
Then I can type n to execute the next statement, s to step into a function, type any object name to see its value, alter execution environment, type c to continue execution…
This is very flexible, works in environments other than PyCharm, where you don’t control the execution environment.
Just type in your virtual environment pip install ipdb and place import ipdb; ipdb.set_trace() on a line where you want the execution to pause.
UPDATE
You can also pip install pdbpp and use the standard import pdb; pdb.set_trace instead of ipdb. PDB++ is nicer in my opinion.
import scrapy
from scrapy.crawler importCrawlerProcessclassMySpider(scrapy.Spider):# Your spider definition...
process =CrawlerProcess({'USER_AGENT':'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'})
process.crawl(MySpider)
process.start()# the script will block here until the crawling is finished
import scrapy
from scrapy.crawler import CrawlerProcess
class MySpider(scrapy.Spider):
# Your spider definition
...
process = CrawlerProcess({
'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'
})
process.crawl(MySpider)
process.start() # the script will block here until the crawling is finished
回答 8
我使用以下简单脚本:
from scrapy.crawler importCrawlerProcessfrom scrapy.utils.project import get_project_settings
process =CrawlerProcess(get_project_settings())
process.crawl('your_spider_name')
process.start()
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
process = CrawlerProcess(get_project_settings())
process.crawl('your_spider_name')
process.start()
I am using pycharm IDE for python development it works perfectly fine for django code so suspected that converting tabs to spaces is default behaviour, however in python IDE is giving errors everywhere because it can’t convert tabs to spaces automatically is there a way to achieve this.
For selections, you can also convert the selection using the “To spaces” function. I usually just use it via the ctrl-shift-A then find “To Spaces” from there.
Open preferences, in macOS ⌘; or in Windows/Linux Ctrl + Alt + S.
Go to Editor -> Code Style -> Python, and if you want to follow PEP-8, choose Tab size: 4, Indent: 4, and Continuation indent: 8 as shown below:
Apply the changes, and click on OK.
If you want to apply the changes just to the current file
Option 1: You can choose in the navigation bar: Edit -> Convert Indent -> To Spaces. (see image below)
Option 2: You can execute “To Spaces” action by running the Find Action shortcut: ⌘⇧A on macOS or ctrl⇧A on Windows/Linux. Then type “To Spaces”, and run the action as shown in the image below.
For me it was having a file called ~/.editorconfig that was overriding my tab settings. I removed that (surely that will bite me again someday) but it fixed my pycharm issue
I’ve set up PyCharm, created my virtualenv (either through the virtual env command, or directly in PyCharm) and activated that environment as my Interpreter. Everything is working just fine.
However, if I open a terminal using “Tools, Open Terminal”, the shell prompt supplied is not using the virtual env; I still have to use source ~/envs/someenv/bin/activate within that Terminal to activate it.
Another method is to activate the environment in a shell, and run PyCharm from that environment. This is “workable” but pretty ugly, and means I have major problems if I switch environments or projects from PyCharm: I’m now using the totally-wrong environment.
Is there some other, much-easier way to have “Tools, Open Terminal” automatically activate the virtual environment?
Auto virtualenv is supported for bash, zsh, fish, and Windows cmd. You
can customize your shell preference in Settings (Preferences) | Tools
| Terminal.
Old Method:
Create a file .pycharmrc in your home folder with the following contents
The preferences in Settings (Preferences) | Tools | Terminal are global.
If you use a venv for each project, remember to use current path variable and a default venv name:
"cmd.exe" /k ""%CD%\venv\Scripts\activate""
For Windows users: when using PyCharm with a virtual environment, you can use the /K parameter to cmd.exe to set the virtual environment automatically.
PyCharm 3 or 4: Settings, Terminal, Default shell and add /K <path-to-your-activate.bat>.
PyCharm 5: Settings, Tools, Terminal, and add /K <path-to-your-activate.bat> to Shell path.
PyCharm 2016.1 or 2016.2: Settings, Tools, Terminal, and add ""/K <path-to-your-activate.bat>"" to Shell path and add (mind the quotes). Also add quotes around cmd.exe, resulting in:
For Windows users when using PyCharm and a virtual environment under Windows, you can use the /k parameter to cmd.exe to set the virtual environment automatically.
Go to Settings, Terminal, Default shell and add /K <path-to-your-activate.bat>.
I don’t have the reputation to comment on the earlier response so posting this corrected version. This really saves a LOT of time.
Update:
Note: Pycharm now supports virtual environments directly and it seems to work well for me – so my workaround not needed anymore.
Based on answers from Peter and experimentation, I’ve come up with a good “general solution”, which solves the following:
Restores the behaviour of a login shell. PyCharm normally runs a login shell, but –rcfile stopped this happening. Script still uses –rcfile, but attempts to emulate the INVOCATION behaviour of a login shell.
Removes the need to create an rcfile for each environment
Removes the need to update the project settings if you change the environment.
Drop this script into a bin directory somewhere. E.g. ~/bin/pycharmactivate
if [ -r "/etc/profile" ] ; then . /etc/profile ; fi
if [ -r "~/.bash_profile" ] ; then
. ~/.bash_profile
elif [ -r "~/.bash_login" ] ; then
. ~/.bash_login
elif [ -r "~/.profile" ] ; then
. ~/.profile
fi
ACTIVATERC=`cat .idea/workspace.xml | perl -n -e 'print "\$1/bin/activate" if m:option name="SDK_HOME" value="\\\$USER_HOME\\\$(.*)/bin/python":'`
if [ -n "$ACTIVATERC" ] ; then . "$HOME/$ACTIVATERC" ; else echo "Could not find virtualenv from PyCharm" ; fi
PyCharm 4 now has virtualenvs integrated in the IDE. When selecting your project interpreter, you can create, add, or select a virtualenv. They’ve added a “Python Console” that runs in the configured project interpreter.
#Stored in ~/.pycharmrc
ACTIVATERC=$(python -c 'import re
import os
from glob import glob
try:
#sets Current Working Directory to _the_projects .idea folder
os.chdir(os.getcwd()+"/.idea")
#gets every file in the cwd and sets _the_projects iml file
for file in glob("*"):
if re.match("(.*).iml", file):
project_iml_file = file
#gets _the_virtual_env for _the_project
for line in open(project_iml_file):
env_name = re.findall("~/(.*)\" jdkType", line.strip())
# created or changed a virtual_env after project creation? this will be true
if env_name:
print env_name[0] + "/bin/activate"
break
inherited = re.findall("type=\"inheritedJdk\"", line.strip())
# set a virtual_env during project creation? this will be true
if inherited:
break
# find _the_virtual_env in misc.xml
if inherited:
for line in open("misc.xml").readlines():
env_at_project_creation = re.findall("\~/(.*)\" project-jdk", line.strip())
if env_at_project_creation:
print env_at_project_creation[0] + "/bin/activate"
break
finally:
pass
')if["$ACTIVATERC"];then."$HOME/$ACTIVATERC";fi
Thanks Chris, your script worked for some projects but not all on my machine. Here is a script that I wrote and I hope anyone finds it useful.
#Stored in ~/.pycharmrc
ACTIVATERC=$(python -c 'import re
import os
from glob import glob
try:
#sets Current Working Directory to _the_projects .idea folder
os.chdir(os.getcwd()+"/.idea")
#gets every file in the cwd and sets _the_projects iml file
for file in glob("*"):
if re.match("(.*).iml", file):
project_iml_file = file
#gets _the_virtual_env for _the_project
for line in open(project_iml_file):
env_name = re.findall("~/(.*)\" jdkType", line.strip())
# created or changed a virtual_env after project creation? this will be true
if env_name:
print env_name[0] + "/bin/activate"
break
inherited = re.findall("type=\"inheritedJdk\"", line.strip())
# set a virtual_env during project creation? this will be true
if inherited:
break
# find _the_virtual_env in misc.xml
if inherited:
for line in open("misc.xml").readlines():
env_at_project_creation = re.findall("\~/(.*)\" project-jdk", line.strip())
if env_at_project_creation:
print env_at_project_creation[0] + "/bin/activate"
break
finally:
pass
')
if [ "$ACTIVATERC" ] ; then . "$HOME/$ACTIVATERC" ; fi
I have viewed all of the answers above but none of them is elegant enough for me. In Pycharm 2017.1.3(in my computer), the easiest way is to open Settings->Tools->Terminal and check Shell integration and Activate virtualenv options.
If You are using windows version it is quite easy.
If you already have the virtual environment just navigate to its folder, find activate.bat inside Scripts folder. copy it’s full path and paste it in pycharm’s terminal then press Enter and you’re done!
If you need to create new virtual environment :
Go to files > settings then search for project interpreter, open it, click on gear button and create the environment wherever you want and then follow first paragraph.
I just added a script named pycharmactivate to my home directory. Set value of PyCharm (4.0.1) File > Settings > Tools > Terminal > Shell path to /bin/bash –rcfile ~/pycharmactivate.
Maybe not the best solution incase you have different project and virtualenv directories/names but it works for me. This script contains the following 3 lines and assumes your virtualenv has the same name as your project dir.
I have a solution that worked on my Windows 7 machine.
I believe PyCharm’s terminal is a result of it running cmd.exe, which will load the Windows PATH variable, and use the version of Python that it finds first within that PATH. To edit this variable, right click My Computer –> Properties –> Advanced System Settings –> Advanced tab –> Environment Variables… button. Within the System variables section, select and edit the PATH variable.
Here is the relevant part of my PATHbefore editing:
To test this, open a new windows terminal (Start –> type in cmd and hit Enter) and see if it’s using your virtual environment. If that works, restart PyCharm and then test it out in PyCharm’s terminal.
this is what i am doing:
create a activate_env.bat(windows,maybe .sh in linux) file in the source code folde:
/env_yourenvlocate/scripts/activate.bat
and another file deactivate_env.bat:
/env_yourenvlocate/scripts/deactivate.bat
everytime open the terminal window, just execute the bat file to activate/deactivate the virtualenv, you will stay in source code path, no need to change path to and back.
If you have moved your project to another directory, you can set the new path via Settings dialog. And then you need to set this Project Interpreter in the Edit Configuration dialog.
Another alternative is to use virtualenvwrapper to manage your virtual environments. It appears that once the virtualenvwrapper script is activated, pycharm can use that and then the simple workon command will be available from the pycharm console and present you with the available virtual environments:
This method should work with arbitrary virtual environments per project and it doesn’t make assumptions on your environment as it is using hooks you create.
You write:
A global script that invokes the hook
A hook script per PyCharm project (not mandatory)
Given that the current latest PyCharm (Community 2016.1) does not allow for Terminal settings per project start with the script that invokes the project specific hook. This is my ~/.pycharmrc:
if [ -r ".pycharm/term-activate" ]; then
echo "Terminal activation hook detected."
echo "Loading Bash profile..."
source ~/.bash_profile
echo "Activating terminal hook..."
source ".pycharm/term-activate"
source activate $PYCHARM_VENV
fi
If you are using something other than Bash, invoke your own .bash_profile equivalent should you wish to.
Now set your PyCharm “Tools -> Terminal -> Shell Path” to invoke this script, e.g.: /bin/bash --rcfile ~/.pycharmrc
Finally, for every PyCharm project you need a specific virtual environment activated, create a file within the PyCharm project root .pycharm/term-activate. This is your hook and it will simply define the name of the desired virtual environment for your PyCharm project:
export PYCHARM_VENV=<your-virtual-env-name>
You can of course extend your hooks with anything you find useful in the terminal environment of your particular PyCharm project.
For conda virtual environments on Windows, make sure your batch file is NOT named activate.bat as this will cause a conflict with the conda activate command, resulting in a recursive calling of the batch file.
I wanted a separate virtual environment for each project, and didn’t care much for having additional files to facilitate this. A solution which you only need to do once and works for all projects is then adding the following to your .bashrc or .bash_profile:
if [ -d "./venv" ]; then
source ./venv/bin/activate
fi
This checks if there is a virtual environment where the terminal is being opened, and if so activates it (and of course other relative paths could be used). PyCharm’s terminal settings can be left as their default.
Then set the shell Preferences->Project Settings->Shell path to
/bin/bash --rcfile ~/.pycharmrc
I don’t why, but it doesn’t work for me. PyCharm prints an error.
cmd.exe /K "<path-to-your-activate.bat>"
It works, but it creates the same virtualenv for each project, and even if this is not necessary.
This receipt is working! But the string /env_yourenvlocate/scripts/activate.bat must contain quotes, like this "Full_path_to_your_env_locate\scripts\activate.bat"!
Deactivate the virtualenv is very easy – type in the terminal ‘deactivate’
The path to your virtualenv in .pycharmrc does not have to be absolute. You can set a project specific virtualenv by setting a relative path from your project directory.
My virtualenv is always located in a ‘venv’ folder under my project directory, so my .pycharmrc file looks like this:
BONUS: automatically open ssh tunnel to connect virtualenv as project interpreter
Add the following to your .pycharmrc file:
if [ $(ps -aux | grep -c 'ssh') -lt 2 ]; then
sudo service ssh start
fi
This checks if a ssh tunnel is already opened, and opens one otherwise.
In File -> Settings -> Project -> Project Interpreter in Pycharm, add a new remote interpreter with following configuration:
Now when you open your project, your bash automatically starts in your virtualenv, opens a ssh tunnel, and pycharm connects the virtualenv as remote interpreter.
warning: the last update in Windows automatically starts a SshBroker and SshProxy service on startup. These block the ssh tunnel from linux to windows. You can stop these services in Task Manager -> Services, after which everything will work again.
I’m trying to split my huge class into two; well, basically into the “main” class and a mixin with additional functions, like so:
main.py file:
import mymixin.py
class Main(object, MyMixin):
def func1(self, xxx):
...
mymixin.py file:
class MyMixin(object):
def func2(self: Main, xxx): # <--- note the type hint
...
Now, while this works just fine, the type hint in MyMixin.func2 of course can’t work. I can’t import main.py, because I’d get a cyclic import and without the hint, my editor (PyCharm) can’t tell what self is.
I’m using Python 3.4, willing to move to 3.5 if a solution is available there.
Is there any way I can split my class into two files and keep all the “connections” so that my IDE still offers me auto completion & all the other goodies that come from it knowing the types?
There isn’t a hugely elegant way to handle import cycles in general, I’m afraid. Your choices are to either redesign your code to remove the cyclic dependency, or if it isn’t feasible, do something like this:
# some_file.py
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from main import Main
class MyObject(object):
def func2(self, some_param: 'Main'):
...
The TYPE_CHECKING constant is always False at runtime, so the import won’t be evaluated, but mypy (and other type-checking tools) will evaluate the contents of that block.
We also need to make the Main type annotation into a string, effectively forward declaring it since the Main symbol isn’t available at runtime.
If you are using Python 3.7+, we can at least skip having to provide an explicit string annotation by taking advantage of PEP 563:
# some_file.py
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from main import Main
class MyObject(object):
# Hooray, cleaner annotations!
def func2(self, some_param: Main):
...
The from __future__ import annotations import will make all type hints be strings and skip evaluating them. This can help make our code here mildly more ergonomic.
All that said, using mixins with mypy will likely require a bit more structure then you currently have. Mypy recommends an approach that’s basically what deceze is describing — to create an ABC that both your Main and MyMixin classes inherit. I wouldn’t be surprised if you ended up needing to do something similar in order to make Pycharm’s checker happy.
For people struggling with cyclic imports when importing class only for Type checking: you will likely want to use a Forward Reference (PEP 484 – Type Hints):
When a type hint contains names that have not been defined yet, that definition may be expressed as a string literal, to be resolved later.
So instead of:
class Tree:
def __init__(self, left: Tree, right: Tree):
self.left = left
self.right = right
you do:
class Tree:
def __init__(self, left: 'Tree', right: 'Tree'):
self.left = left
self.right = right
The bigger issue is that your types aren’t sane to begin with. MyMixin makes a hardcoded assumption that it will be mixed into Main, whereas it could be mixed into any number of other classes, in which case it would probably break. If your mixin is hardcoded to be mixed into one specific class, you may as well write the methods directly into that class instead of separating them out.
To properly do this with sane typing, MyMixin should be coded against an interface, or abstract class in Python parlance:
import abc
class MixinDependencyInterface(abc.ABC):
@abc.abstractmethod
def foo(self):
pass
class MyMixin:
def func2(self: MixinDependencyInterface, xxx):
self.foo() # ← mixin only depends on the interface
class Main(MixinDependencyInterface, MyMixin):
def foo(self):
print('bar')
回答 3
事实证明,我最初的尝试也非常接近解决方案。这是我目前正在使用的:
# main.pyimport mymixin.py
classMain(object,MyMixin):def func1(self, xxx):...# mymixin.pyifFalse:from main importMainclassMyMixin(object):def func2(self:'Main', xxx):# <--- note the type hint...
请注意,import inside if False语句永远不会被导入(但IDE仍然知道它),并且将该Main类用作字符串,因为在运行时不知道。
Turns out my original attempt was quite close to the solution as well. This is what I’m currently using:
# main.py
import mymixin.py
class Main(object, MyMixin):
def func1(self, xxx):
...
# mymixin.py
if False:
from main import Main
class MyMixin(object):
def func2(self: 'Main', xxx): # <--- note the type hint
...
Note the import within if False statement that never gets imported (but IDE knows about it anyway) and using the Main class as string because it’s not known at runtime.
I think the perfect way should be to import all the classes and dependencies in a file (like __init__.py) and then from __init__ import * in all the other files.
In this case you are
avoiding multiple references to those files and classes and
also only have to add one line in each of the other files and
the third would be the pycharm knowing about all of the classes that you might use.
I realize this is old but I figured I’d clear up a misconception for other travelers. Setting plt.pyplot.isinteractive() to False means that the plot will on be drawn on specific commands to draw (i.e. plt.pyplot.show()). Setting plt.pyplot.isinteractive() to True means that every pyplot (plt) command will trigger a draw command (i.e. plt.pyplot.show()). So what you were more than likely looking for is plt.pyplot.show() at the end of your program to display the graph.
As a side note you can shorten these statements a bit by using the following import command import matplotlib.pyplot as plt rather than matplotlib as plt.
I tried different solutions but what finally worked for me was plt.show(block=True). You need to add this command after the myDataFrame.plot() command for this to take effect. If you have multiple plot just add the command at the end of your code. It will allow you to see every data you are plotting.
I test in my version of Pycharm (Community Edition 2017.2.2), you may need to announce both plt.interactive(False) and plt.show(block=True) as following:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 6.28, 100)
plt.plot(x, x**0.5, label='square root')
plt.plot(x, np.sin(x), label='sinc')
plt.xlabel('x label')
plt.ylabel('y label')
plt.title("test plot")
plt.legend()
plt.show(block=True)
plt.interactive(False)
回答 6
我找到了解决方案。这对我有用:
import numpy as np
import matplotlib.pyplot as plt
points = np.arange(-5,5,0.01)
dx, dy = np.meshgrid(points, points)
z =(np.sin(dx)+np.sin(dy))
plt.imshow(z)
plt.colorbar()
plt.title('plot for sin(x)+sin(y)')
plt.show()
Comment from DanT fixed this for me, matplotlib with pycharm on linux with the GTKagg backend. Upon importing matplotlib I would get the following error:
>>> import matplotlib as mpl
Backend GTKAgg is interactive backend. Turning interactive mode on.
Failed to enable GUI event loop integration for 'gtk'
When plotting something like so:
from matplotlib import pyplot as plt
plt.figure()
plt.plot(1,2)
plt.show()
A figure screen would pop up but no charts appear.
using:
For those who are running a script inside an IDE (and not working in an interactive environment such as a python console or a notebook), I found this to be the most intuitive and the simplest solution:
plt.imshow(img)
plt.waitforbuttonpress()
It shows the figure and waits until the user clicks on the new window. Only then it resume the script and run the rest of the code.
I was able to get a combination of some of the other suggestions here working for me, but only while toggling the plt.interactive(False) to True and back again.
plt.interactive(True)
plt.pyplot.show()
This will flash up the my plots. Then setting to False allowed for viewing.
plt.interactive(False)
plt.pyplot.show()
As noted also my program would not exit until all the windows were closed. Here are some details on my current run environment:
Python version 2.7.6
Anaconda 1.9.2 (x86_64)
(default, Jan 10 2014, 11:23:15)
[GCC 4.0.1 (Apple Inc. build 5493)]
Pandas version: 0.13.1
回答 20
需要为pycharm设置一个属性。
import matplotlib.pyplot as plt
plt.interactive(False)#need to set to False
dataset.plot(kind='box', subplots=True, layout=(2,2), sharex=False, sharey=False)
plt.show()
import matplotlib.pyplot as plt
plt.interactive(False) #need to set to False
dataset.plot(kind='box', subplots=True, layout=(2,2), sharex=False, sharey=False)
plt.show()
In Pycharm , at times the Matplotlib.plot won’t show up.
So after calling plt.show() check in the right side toolbar for SciView. Inside SciView every generated plots will be stored.
回答 24
我在尝试绘制直方图时遇到上面的错误,而下面的点对我有用。
操作系统:Mac Catalina 10.15.5
Pycharm版本:社区版本2019.2.3
Python版本:3.7
我将导入语句更改如下(从-到)
来自:
import matplotlib.pylab as plt
至:
import matplotlib.pyplot as plt
和下面的绘图语句(将我的命令表pyplot更改为plt)
从:
plt.pyplot.hist(df["horsepower"])# set x/y labels and plot title
plt.pyplot.xlabel("horsepower")
plt.pyplot.ylabel("count")
plt.pyplot.title("horsepower bins")
至 :
plt.hist(df["horsepower"])# set x/y labels and plot title
plt.xlabel("horsepower")
plt.ylabel("count")
plt.title("horsepower bins")
I was facing above error when i am trying to plot histogram and below points worked for me.
OS : Mac Catalina 10.15.5
Pycharm Version : Community version 2019.2.3
Python version : 3.7
I changed import statement as below (from – to)
from :
import matplotlib.pylab as plt
to:
import matplotlib.pyplot as plt
and plot statement to below (changed my command form pyplot to plt)
from:
plt.pyplot.hist(df["horsepower"])
# set x/y labels and plot title
plt.pyplot.xlabel("horsepower")
plt.pyplot.ylabel("count")
plt.pyplot.title("horsepower bins")
to :
plt.hist(df["horsepower"])
# set x/y labels and plot title
plt.xlabel("horsepower")
plt.ylabel("count")
plt.title("horsepower bins")
In addition, one cannot annotate variables used in a for or with
statement; they can be annotated ahead of time, in a similar manner to
tuple unpacking
Annotate it before the loop:
i: int
for i in range(5):
pass
PyCharm 2018.1 and up now recognizes the type of the variable inside the loop. This was not supported in older PyCharm versions.
None of the responses here were useful, except to say that you can’t. Even the accepted answer uses syntax from the PEP 526 document, which isn’t valid python syntax. If you try to type in
x: int
You’ll see it’s a syntax error.
Here is a useful workaround:
for __x in range(5):
x = __x # type: int
print(x)
Do your work with x. PyCharm recognizes its type, and autocomplete works.