Can I remove a method from a ready module in python? Recently i was trying to write a python code in a browser based trading platform where in they allow usto import python 'time' package but the time package didn't have sleep() method. While i was trying to import sleep method it gave me attribute error. On asking the technical support people of that platform i got to know that they don't support sleep() method. I am just wondering how could we do that? is it just deleting the method from the package? Or are there any better ways?
It is possible to remove methods (functions) from a name space at run time.
This is called monkey patching. Example in an interactive session:
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import time
>>> time.sleep(2)
>>> del time.sleep
>>> time.sleep(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'sleep'
But back to your original question: I believe that on the platform you are using they might have replaced several standard library modules (including the time module) with customized versions. So you should ask them how you can achieve the delay you want without having to resort to busy waiting.
import time
time.sleep(1)
del time.sleep
time.sleep(1)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-6-07a34f5b1e42> in <module>()
----> 1 time.sleep(1)
AttributeError: 'module' object has no attribute 'sleep'
If you don't have the time.sleep method, you can easily write your own (albeit not likely as precise or efficient):
def sleep(seconds):
a = time.time()
b = time.time()
while b - a < seconds:
b = time.time()
Here are some tests for precision that I ran (only a print statement to see how often it went into the loop):
>>> sleep(1)
2.86102294922e-06
0.0944359302521
0.14835691452
0.198939800262
0.249089956284
0.299441814423
0.349442958832
0.398970842361
0.449244022369
0.498914003372
0.549893856049
0.600338935852
0.648976802826
0.700131893158
0.750012874603
0.800500869751
0.850263834
0.900727987289
0.950336933136
1.00087189674
The precision stays at 100th mile seconds precision. :)
You might not have the method either because they modified the source code, or ran some things on the interpreter before your code began executed (using the del keyword like in the other answers).
Related
I am learning sympy, and wanted to verify the solution to an ODE. I do not yet quite understand sympy naming conventions.
Instead of doing the standard methods of loading all packages at the top, I wanted to just import sympy and then use explicit long name to reference any other name inside sympy. On latest conda python
Python 3.7.3 (default, Mar 27 2019, 22:11:17)
[GCC 7.3.0] :: Anaconda, Inc. on linux
When typing
import sympy
x = sympy.symbols('x')
y = sympy.Function('y')
ode = sympy.Eq(sympy.Derivative(y(x),x),1+2*x)
sol = sympy.dsolve(ode,y(x))
sympy.solvers.ode.checkodesol(ode,sol)
And the above gives error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'sympy.solvers.solvers' has no attribute 'ode'
But from the page https://docs.sympy.org/latest/modules/solvers/ode.html
It says
But if I do the following, it works
from sympy import checkodesol
checkodesol(ode,sol)
(True, 0)
But I do not want to import checkodesol explicitly. I want to just import sympy and then use the long name to call checkodesol or any other sympy sub packages, as this makes it more clear to me in the code where each function is coming from (at the cost of a little extra typing)
The question is, why using sympy.solvers.ode.checkodesol does not work?
At the very top of the documentation you linked to, it says
These are functions that are imported into the global namespace with
from sympy import *. These functions (unlike Hint Functions, below)
are intended for use by ordinary users of SymPy.
Then you can use checkodesol(ode, sol) directly.
If you do import sympy, then you need to call
sympy.checkodesol(ode, sol)
This is a bit QGIS specific, but figure it's kind of low level so I've posted here. I can definitely move this over to gis.stackexchange.com if that's better.
Trying to use QgsRasterCalculator, which seems to want a QString type object for a couple of arguments. I try to create a QString (like described here) but get:
import PyQt4
PyQt4.QtCore.QString('foo')
Traceback (most recent call last):
File "<input>", line 1, in <module>
AttributeError: 'module' object has no attribute 'QString'
So I try to use a regular string for my first argument (calc = QgsRasterCalculator( 'demffac > 120', newStreams, 'GTiff', rFac.extent(), rFac.crs().authid(), rFac.height(), rFac.width(), entries)), I got:
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: arguments did not match any overloaded call:
QgsRasterCalculator(QString, QString, QString, QgsRectangle, int, int, list-of-QgsRasterCalculatorEntry): argument 5 has unexpected type 'unicode'
QgsRasterCalculator(QString, QString, QString, QgsRectangle, QgsCoordinateReferenceSystem, int, int, list-of-QgsRasterCalculatorEntry): argument 5 has unexpected type 'unicode'
QgsRasterCalculator(QgsRasterCalculator): argument 1 has unexpected type 'str'
I'm using QGIS 2.14, which has been documented as using QString (as I understand it). I've tried to use the sip package to reset (per these instructions) but QGIS's python console doesn't seem to want to change (ValueError: API 'QString' has already been set to version 2).
Any way to make my QgsRasterCalculator() call work? Thanks for any info!
/==================EDIT: screen grab of my QGIS's responses to suggestions=========
/==================
Version info:
from PyQt4.QtCore import QT_VERSION_STR
from PyQt4.pyqtconfig import Configuration
print("Qt version:", QT_VERSION_STR)
('Qt version:', '4.8.5')
cfg = Configuration()
print("SIP version:", cfg.sip_version_str)
('SIP version:', '4.14.7')
print("PyQt version:", cfg.pyqt_version_str)
('PyQt version:', '4.10.2')
Looking more closely at the traceback, it seems that QgsRasterCalculator does not require the use of QString. This is proved by the fact that you passed python strings for the first three arguments, and the error message does not complain about them at all. Rather, it complains about the fifth argument, which must be either an int or QgsCoordinateReferenceSystem object, whereas you seem to be passing in unicode or str objects. Why are you passing in the return value of rFac.crs().authid()? Surely you should be passing in rFac.crs(), rather than authid() (which is documented as returning a string).
With regard to potential issues with QString:
When used with Python2, PyQt4 most definitely does have the QString class - unless you take explicit steps to change that by using the sip module. The code at the beginning of your question is not what you actually ran, because it does not raise that specific error:
Python 2.7.15 (default, Jun 27 2018, 13:05:28)
[GCC 8.1.1 20180531] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import PyQt4
>>> PyQt4.QtCore.QString('foo')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'QtCore'
If you import the QtCore module properly, the code works fine:
>>> from PyQt4 import QtCore
>>> QtCore.QString('foo')
PyQt4.QtCore.QString(u'foo')
Note that it never makes sense to import the PyQt4 package on its own. It is just an empty namespace which (for performance reasons) imports the other modules lazily. You must therefore always import the Qt modules explicitly as I have done above.
PS:
In the second half of your question, it seems that the PyQt APIs have somehow already been changed to version 2, which will switch off support for QString. To switch it back on, you would need to do:
import sip
sip.setapi('QString', 1)
However, this step must be done before any other PyQt modules are imported.
I am facing an issue I faced a few times so far.
The issue in question just gets solved by itself every time, without me understanding what is causing it
So what happens is that I start a python virtual environment from my c++ code. That works, afterwards by using the write function I am able to write stuff in that environment. This also works perfectly fine so far. However I am unable to write my last command to the process.
I though about maybe some buffer being full but I didn't really find anything about a buffer in the Qt docs
This is the relevant piece of code:
static QStringList params;
QProcess *p = new QProcess();
params<<"-f"<<"-c"<<"python2"<< "/home/John/Desktop/python.log";
qDebug()<<"parameters: "<<params;
qDebug()<<"going to write";
p->start("script", params);
qDebug()<<"Turning on new user process...";
while(!p->waitForStarted())
{qDebug()<<"waiting for virtualenv to be ready";}
successFailWrite = p->write("import imp;\n");
while(!p->waitForBytesWritten());
successFailWrite = p->write("foo = imp.load_source('myTest', '/home/John/recognitionClass.py');\n");
while(!p->waitForBytesWritten());
successFailWrite = p->write("from myTest import recognitionClass;\n");
while(!p->waitForBytesWritten());
successFailWrite = p->write("myClassObj = recognitionClass();\n");
if(successFailWrite !=-1)
{qDebug()<<"OK written";}
while(!p->waitForBytesWritten());
successFailWrite = p->write("habelahabela\n");
if(successFailWrite !=-1)
{qDebug()<<"OK written";}
QString name = "John";
QString processNewUserParameter= "print myClassObj.addNewUser("+ name +");\n";
QByteArray processNewUserParameterByteArr= processNewUserParameter.toUtf8();
p->write(processNewUserParameterByteArr);
I keep a log file which contains what is being written to the python virtualenv and what is being printed
Script started on Son 27 Aug 2017 20:09:52 CEST
import imp;
foo = imp.load_source('myTest', '/home/John/recognitionClass.py');
from myTest import recognitionClass;
myClassObj = recognitionClass();
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import imp;
>>> foo = imp.load_source('myTest', '/home/John/recognit
<myTest', '/home/John/recogniti onClass.py');
/usr/local/lib/python2.7/dist-packages/sklearn/cross_validation.py:44: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.
"This module will be removed in 0.20.", DeprecationWarning)
/usr/local/lib/python2.7/dist-packages/sklearn/grid_search.py:43: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. This module will be removed in 0.20.
DeprecationWarning)
>>> from myTest import recognitionClass;
>>> myClassObj = recognitionClass();
>>>
It does pront "OK written" twice, which on one side proves that I successfully wrote my commands to the process, yet I can't see anything.
As you can see the test sentence "habelahabela" doesn't get written neither.
Does anybody have an idea about what I may be doing wrong?
I know that I am writing my commands to quickly to the environment. Because as you can see I start by writing "import imp", it then gets buffered and a little later the buffer gets flushed and the virtualenv executes the command (this is why you see it twice).
Does anybody see why I can't see the test-sentence and -more importantly- my actual command "print myClassObj.addNewUser("+ name +");\n" being printed to the virtual environment?
Thanks
First of all, there is no sense in writing while(!p->waitForBytesWritten());. waitForBytesWritten already blocks your thread without a while loop and, as the name states, waits until bytes are written. It returns false only if there are either timeout or an error. In the first case you should give it more time to write bytes. In the second case you should fix the error and only then try again.
The same holds for waitForStarted and all other Qt functions starting with "waitFor...".
So the usage looks like:
if(!p->waitForBytesWritten(-1)) // waits forever until bytes ARE written
{
qDebug() << "Error while writing bytes";
}
Regarding the question: I believe the problem (or at least a part of it) is that you write your last 2 messages into p, but you neither wait for bytesWritten() signal, nor use waitForBytesWritten() blocking function. Although, there is probably no error occuring (because p->write(...) does not return -1 at that point), however it does not mean that your message is written yet. In a nutshell, wait for bytesWritten() signal...
QProcess inherits from QIODevice, so I recommend to look its docs and learn about it a bit more.
Inside the shell, I get the following response when I try to import my program.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "tweet.py", line 26
print "Favorited: %s" % (result['text'])
^
SyntaxError: invalid syntax
Why does print "Favorited: %s" % (result['text']) return an error? Googling has been unhelpful, this was working for me earlier...
Update, I'm running the following version of Python:
Python 2.7.5 |Anaconda 1.6.1 (x86_64)| (default, Jun 28 2013, 22:20:13)
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Update again, here is the function:
def fetch_tweet(tweet):
try:
result = t.favorites.create(_id=tweet['id'])
print "Favorited: %s" % (result['text'])
return result
# when you have already favourited a tweet, this error is thrown
except TwitterHTTPError as e:
print "Error: ", e
return None
Update #3 - found the error!
Turns out my python interpreter really hated a bit of code I had at the top, which was messing with print somehow - I deleted from __future__ import print_function from the top of the file and everything started working smoothly.
I see you got it working, but here's the explanation:
Python 3 changed how printing works for various reasons. The big change is that print is now a function instead of a statement (this is helpful because it allows you to, say, pass parameters to it if you want to change things like where it prints to, whether to terminate with a newline, etc)
So when you had the line:
from __future__ import print_function
It was using Python 3 printing, but you're running in Python 2. One solution (as you found) is to remove the import, but you could also change the print statement to a function. For simple statements like this you just need to add parens, so this would have worked:
print("Favorited: %s" % (result['text']))
These would also work:
print("Favorited: {}".format(result['text']))
print("Favorited:", result['text'])
I'm trying to write a Python program to deal with RSS, however I'm having some issues downloading the files directly from the internet.
I am using urllib.request.urlopen() to get the files. Here is the bit of code that I am having trouble with:
import xml.etree.ElementTree as et
import urllib.request as urlget
self.sourceUrl = sourceUrl #sourceUrl was an argument
self.root = et.fromstring(urlget.urlopen(sourceUrl).read())
I have tracked the problem down to a single line:
urllib.request.urlopen calls urllib.request.opener.open()
which then calls self._open()
which then calls self._call_chain()
which then calls urllib.request.HTTPHandler.http_open()
which then calls urllib.request.AbstractHTTPHandler.do_open()
which then calls http.client.HTTPConnection.getresponse()
which then calls http.client.HTTTResponse.begin()
which then calls self._read_status()
Problem line (found by being the only line to appear upon pausing execution many times):
Python33\Lib\http\client.py Line 317
if len(line) > _MAXLINE:
I can continue the code, but only if I babysit it through Step Over until I get back to my code.
In my tests, this problem never occurred, so I can't think if why I am getting it now.
Thanks in advance for any help!
EDIT: Source can be found here. I lost motivation to work on this project quite some time ago, and haven't touched it since. I might redo the entire thing if I get some more motivation, but I don't expect to any time soon. If you wish to answer, I invite you to have at it, it might be beneficial to others. Be warned, however, that the code is terrible, as at the time I had relatively little experience. I can't really find my way around it, but I've figured out that you have to look at data/code/functions.py
Also note, that, as far as I can remember, it wasn't calling an error, it was just that the program was hanging for minutes at a time before I got impatient.
Without more code, it will be hard to help you. What is the URL of your feed. What does it return when you try to simply access it.
Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 01:25:11)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import xml.etree.ElementTree as et
>>> import urllib.request as urlget
>>> sourceurl = "http://www.la-grange.net/feed"
>>> root = et.fromstring(urlget.urlopen(sourceurl).read())
>>> root
<Element '{http://www.w3.org/2005/Atom}feed' at 0x1013a82b8>
>>>