I think this is a really silly / dumb question, but I am using PyCharm and constantly adding methods to a class or changing the body of the methods. When I test the class by importing the .py file and initiating the class object, it doesnt seem to recognize the changes to the class.
Is there some button I need to hit to make sure that the class code is changed.
The only thing that seems to work for me is to restart PyCharm.
When you import the class, it imports it as-is at the current time. If you make changes after that, you need to import it again. In this case, you should just be able to terminate the shell, and start it again.
This is not an error, or a bug.
There many variations of the issue you have stated.
One issue I have faced is having two classes in the module - one containing another's object.
e.g.
class y:
#classmethod
def f1():
print('old')
class x:
def __init__(self):
self.ref_cls = y()
def test():
self.ref_cls.f1() # <-- "line to change"
Now if I place a breakpoint over "line to change" and want to redef f1 to print 'new' instead of 'old', I open the evaluator and add following code:
class new: # <-- if you write 'y' instead of new it does not work
#classmethod
def f1():
print('new')
self.ref_cls = new
Evaluate this and then step over to confirm in the console.
This works for static methods and object methods as well.
Hope this helps.
Related
I have written a class in python 3.8 and for reasons, I need some of the class methods to be defined in a different file. The method I used for putting this function as the class method was by adding it later with setattr. This allows me to selectively add methods I want, I wont get into too many details on that because its irrelevant
myClass.py:
# This bit will scan the external file and add relevant methods to the class via a decorator
# just to give an idea, don't get hungh up on the implementation
def add_methods():
def decorator(Class):
import methods from external.py
for method in external.py:
if method is what I want:
setattr(Class, method_name, method)
#add_method()
def myClass():
def __init__(self):
dostuff
def method_1(self, arg1 , arg2):
dostuff
def method_2(self, arg1 , arg2, arg3):
dostuff
Inside another folder, we got the method file I mentioned
method_folder/external.py
def ext_added_method_1(self):
do stuff here
def ext_added_method_2(self):
do stuff here
Then finally, the class is used by a code
main.py
from myClass import myClass
handler = myClass()
dostuff
This all works just fine, the externally added methods are there and work just as expected. but there is one annoying bit that is when I'm working on the 'external.py' file which is where most of the coding is done anyway. My VSCode understandably does not know what is inside of the 'self' parameter of ext_added_method_1 and ext_added_method_2, so there is no linting.
The question is, is there a way of telling vscode, that on external.py, the 'self' parameter should be linted from the myClass object?
I don't need linting of the methods inside external.py (ext_added_method_1 and ext_added_method_2) I know that would be impossible since they are dynamically added. But for the methods that are defined in myClass.py, such as method_1 and method_2 I would like to have autocomplete and all that magical stuff.
Any way to achieve that without changing the architecture?
thank you!
Thx rioV8m, I wasn't familiar with that term. But then I looked it up and came up with the following solution
external.py
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from myClass import myClass
def ext_added_method_1(self: 'myClass'):
do stuff here
def ext_added_method_2(self: 'myClass'):
do stuff here
With that import check, I have no issues with circular imports so it basically ignores that, but is enough for VSCode to pick up on the class.
Also, I add the type in single quotes which are called 'forward references'. This is then only used by the editor to inform it of the class contents.
I have a base class, Sample and a derived class SignalSample, and the code for both of these classes normally resides within the same file Sample.py.
I import these classes into my main script in the usual way: from Sample import Sample, SignalSample
While chasing down a bug within one of these classes, I noticed some unusual behavior: deleting the code for the SignalSample derived class changed the behavior of the Signal base class.
So my question is, can the existence of a derived class alter a base class, even if the derived class is never instantiated?
To be concrete, I tried the following combinations.
The code for Sample and SignalSample are both in Sample.py. from Sample import Sample, SignalSample is used in my main script to load these classes. Sample objects are instantiated, there are no SignalSample objects instantiated, the code is just there and unused. In this scenario, I get an error which I will call "type 1".
Delete the code for SignalSample inside Sample.py, and remove the ... import SignalSample statement. In this case, I get a different error which I'll call "type 2".
Note that I don't think the errors are coming from the classes themselves (although they may be), it was more that I found it interesting that the behavior of the code seemed to change because there was an inherited class, even though that class was not used.
This is a stripped-down example of my setup, note that this is not an MWE of the source of my bug, as at the moment I don't know where it is coming from, and so I can't even narrow it down. It's not the solution to the bug I'm looking for, just more information on this seemingly strange behavior of class inheritance.
# file Sample.py
class Sample:
def __init__(self):
self._tfile = None
self._filepath = None
def calculate_filepath(self):
return "my/file/path"
__calculate_filepath = calculate_filepath # private copy
def get_histogram(self, histogram_name):
if not self._filepath:
self._filepath = self.calculate_filepath()
if not self._tfile:
from ROOT import TFile # this is a special filetype
self._tfile = TFile.Open(self._filepath, "READ")
histo = self._tfile.Get(histogram_name)
histo.SetDirectory(0)
self._tfile.Close()
return histo
class SignalSample(Sample):
def __init__(self):
# Inherit
Sample.__init__(self)
self._filepath = self.calculate_filepath()
def calculate_filepath(self):
# Overloaded version of the function in Sample
return "my/very/special/filepath"
Note that I chose to call the calculate_filepath method inside get_histogram because I wanted to avoid possible namespace clashes with the derived class. This is also why I try to make the method "private" with the namespace mangling. This is also why I open the special TFile file inside the get_histogram method, although it is nice that I can then also Close this file inside the same function. Perhaps this isn't the correct usage and maybe this related to the source of my problem?
get_histogram looks potentially broken if it is called more than once. You assign the opened file to the instance (on self._tfile), but then close it before returning... that means that next time the method is called not self._tfile will probably (*) evaluate to False, meaning that you then try to call Get on a closed file. If you are using a sane library this would probably throw a nice error telling you this, but I see you're using ROOT so who knows what might happen :)
Probably simplest would be not to store the file on Sample, and just open the file whenever get_histogram is called?
(*) Implicit booliness is sometimes worth avoiding. In particular when what you actually want to check is whether something is None, prefer writing if x is None: ( https://legacy.python.org/dev/peps/pep-0008/#programming-recommendations )
Incidentally, in this example, __calculate_filepath = calculate_filepath # private copy isn't doing anything, since you never actually use it.
As you know, when the project's code is very large and there are so many attributes and functions defined in a Class, but some of them never be called by the instance of the Class, and maybe some of them has been discarded. Here is a example:
class Foo(object):
""""""
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
...
self.y = 25
self.z = 26
def func1(self):
pass
def func2(self):
pass
def func3(self):
pass
...
...
def func100(self):
pass
if __name__ == '__main__':
f = Foo()
f.func1()
f.func2()
print f.a, f.b, f.z
In the above code, the instance f of class Foo just called func1() and func2(). And how to find all the attributes and functions of class that never called by the instance of class.
I have tried compiler module but that could not solve my question. And dir(my_instance) is just print all the functions and attributes defined the the class.
Thanks in advance.
You can try coverage.py. It's not static analysis, but actually runs your code and records which statements are executed, outputting annotated html or txt as you wish (quite nicely formatted as well). You can then look for functions and methods whose bodies are not executed at all.
This still doesn't take care of unused attributes. And I don't know the answer to that. Maybe comment them out one at a time and see if tests still pass...
It's pretty hard to prove something is or is not used in the general case. Python is a dynamic language; if even one bit of code calls into code the static analyzer doesn't fully analyze, it could be accessing the variables mentioned.
The pylint and flake8 tools will tell you about local and global names that aren't defined prior to use (unless you break them by using from x import * style imports), and about imports that are never used (an import that is never used is usually wrong, but even then, it could be an intentional part of the interface, where linters would have to be silenced), but I don't believe they can tell you that a given attribute is never accessed; after all, someone else could import your module and access said attributes.
Use the profile module in the standard library.
python -m cProfile -o output_file myscript.py
Then load the stats file and use print_callees() to get all the functions that were called--during that run of the program.
I don't know of any easy way to find out which attributes are used.
I've been playing with my codes a little for a while, and this one is not about a bug or anything, but i just don't understand why class main() runs without needing to initialize it...
class vars():
var1 = "Universe!"
var2 = "Oscar!"
var3 = "Rainbow!"
class main():
print (vars.var1)
def __init__(self):
print (vars.var2)
print (vars.var3)
But yes, thank you very much for reading.
Unlike many other languages, class body is an executable statement in Python and is executed immediately as the interpreter reaches the class line. When you run this "program":
class Foo:
print("hey")
it just prints "hey" without any Foo object being created.
The same applies to the function definition statement def (but not to function bodies). When you run this:
def foo(arg=print("hi")):
print("not yet")
it prints "hi", but not "not yet".
When a class is created, Python executes all of the code directly inside the class declaration in a new namespace. This is so that any variables created in the class (most commonly methods, created by ordinary function declarations like def foo(self...)) are attached to the class rather than being global.
But the code still runs immediately. If it calls print() or does something else which creates a visible side effect, that will happen now, not when the class is instantiated (called to create a new instance). If you need something to happen when the class is instantiated, write an __init__() method instead.
main is a class not a function. Thus the code contained in the class declaration runs immediately because all statements are executed as they appear in code. As a method declaration is reached, it's bound to the class as a member, so in a way methods execute as well but are not called.
When Python read your code, it looked into class vars and defined all the variables. Then, it went into class main and executed the code there, as well as defining init. Python just executes whatever which is not in a function definition.
Relatively new to Python, and I saw the following construct in the PyFacebook library (source here: http://github.com/sciyoshi/pyfacebook/blob/master/facebook/init.py#L660). I'm curious what this does because it appears to be a class that inherits from itself.
class AuthProxy(AuthProxy):
"""Special proxy for facebook.auth."""
def getSession(self):
"""Facebook API call. See http://developers.facebook.com/documentation.php?v=1.0&method=auth.getSession"""
...
return result
def createToken(self):
"""Facebook API call. See http://developers.facebook.com/documentation.php?v=1.0&method=auth.createToken"""
...
return token
what is this doing?
Tangentially related, I'm using PyDev in Eclipse and it's flagging this as an error. I'm guessing that's not the case. Anyway to let Eclipse know this is good?
The class statement there doesn't make the class inherit from itself, it creates a class object with the current value of AuthProxy as a superclass, and then assigns the class object to the variable 'AuthProxy', presumably overwriting the previously assigned AuthProxy that it inherited from.
Essentially, it's about the same as x = f(x): x isn't the value of f on itself, there's no circular dependence-- there's just the old x, and the new x. The old AuthProxy, and the new AuthProxy.
It's using the AuthProxy imported from a different module (check your imports) and deriving from it.
The "former" AuthProxy is created by __generate_proxies (it's not very nice code, there is even an exec and eval in it :)), but the author wanted also define some methods on top of it.
To make Eclipse stop whining about it, do this:
class AuthProxy(AuthProxy): ##UndefinedVariable