Python Inheritance initialize problems - python

I have threading class in serverThread.py file as shown:
import threading
class serverThread(threading.Thread):
def __init__(self, name):
try:
threading.Thread.__init__(self)
self.name = name
except:
exit()
def run(self):
print("Hello")
I created a new project.I want to inherit class from above class as shown:
import serverThread
class tcpThread(serverThread):
def __init__(self, name):
serverThread.__init__(self,name)
def run():
serverThread.run(self)
t1 = tcpThread("Tcp Server")
t1.start()
When I run this script gives me error:
Error:
Traceback (most recent call last): File "serverTcpThread.py", line 4, in <module> class tcpThread(serverThread): TypeError: module.&lowbar;&lowbar;init&lowbar;&lowbar;() takes at most 2 arguments (3 given)

The error you're reporting is probably because the base class is imported from a bad path, cannot reproduce here.
That said, there's another (similar) error: when redefining the run method, you have to pass the self parameter
class tcpThread(serverThread):
def __init__(self, name):
serverThread.__init__(self,name)
def run(self):
serverThread.run(self)
the code runs fine after that. note that there's no need to redefine the run method only to call the parent method.

Related

Cannot find metaclass in module

I seem to be running into a problem where I can't inherit from another class in the same module. Here's the MCVE I came up with.
The (uninteresting) contents of main.py:
#!/usr/bin/python
import foobar
if __name__ == "__main__":
print("Hello, World!")
The contents of foobar/__init__.py:
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
from foobar.this_one_works import Pucker
from foobar.csend import Csend
That Singleton class up there is shamelessly copy-pasted from here.
It's important to note that __init__ successfully imports the Pucker class from this_one_works.py. Here is the contents of the latter file:
class PuckerMeta():
def __init__(self):
pass
class Pucker(metaclass=PuckerMeta):
def __init__(self):
pass
The contents of foobar/csend.py:
class Csend(metaclass=Singleton):
def __init__(self):
pass
And now running main.py gives the following error:
Traceback (most recent call last):
File "/home/sam/mcve/python/./main.py", line 3, in <module>
import foobar
File "/home/sam/mcve/python/foobar/__init__.py", line 9, in <module>
from foobar.csend import Csend
File "/home/sam/mcve/python/foobar/csend.py", line 1, in <module>
class Csend(Singleton):
NameError: name 'Singleton' is not defined
I'm puzzled about the fact that importing foobar seems to find PuckerMeta okay, but not Singleton. Is there anything special about a class that's defined in __init__.py that means it can't be inherited from or something?
Oh and in case it matters, I'm on Python 3.9.2.

Why am I able to instantiate my Abstract Base Class in Python?

As I understand it, I can use the abc module in Python to create abstract classes that can't be instantiated (amongst other nice properties). I tried to use this to create a hierarchy of Exception classes to represent various exit codes for my application, but I'm still able to instantiate my base class, even though I don't want that to happen. Here's some code that demonstrates the problem:
#!/usr/bin/env python3
import abc
class ExitCodeException(Exception):
__metaclass__ = abc.ABCMeta
def __init__(self, message):
super().__init__()
self._message = message
#abc.abstractmethod
def getExitCode(self):
"""Return the exit code for this exception"""
return
class FatalException(ExitCodeException):
def getExitCode(self):
return 1
raise ExitCodeException("Oh no!")
I was expecting my program to quit with an exception saying that ExitCodeException couldn't be instantiated, but instead I just get the standard stack trace I'd expect if ExitCodeException weren't abstract:
Traceback (most recent call last)
File "./email2pdf_classexception", line 21, in <module>
raise ExitCodeException("Oh no!")
__main__.ExitCodeException
How can I fix this?
As discussed in the comments by #BartoszKP and #Debanshu Kundu above, it appears the concrete superclass Exception is what causes the issue here. As such, I've come up with a slightly different pattern which seems to work (as I understand it, this is an older-style of pattern from Python 2, but still seems valid):
#!/usr/bin/env python3
class ExitCodeException(Exception):
def __new__(cls, *args, **kwargs):
if cls is ExitCodeException:
raise NotImplementedError("Base class may not be instantiated")
return Exception.__new__(cls, *args, **kwargs)
def __init__(self, message):
super().__init__()
self._message = message
def getExitCode(self):
"""Return the exit code for this exception"""
return
class FatalException(ExitCodeException):
def getExitCode(self):
return 1
raise FatalException("Oh no!")
This works as intended; if I change the code to instantiate ExitCodeException directly, it fails.

Python GTK3 inheritance

How can I inherit a GTK+3 class in python ? I'm trying to create a inherited class of Gtk.Application and what I got is a segfault.
I've tried a lot of things, but with this I got a segfault:
class Program(Gtk.Application):
def __init__(self):
super().__init__(self)
...
prg = Program.new("app_id", flags)
if I try your code snippet I actually get:
Traceback (most recent call last):
File "pyclass.py", line 12, in <module>
prg = Program.new("app_id", 0)
TypeError: Application constructor cannot be used to create instances of a subclass Program
which is expected, since you're trying to call the Python wrapper for gtk_application_new() by using Program.new().
you should use the Python constructor form:
class Program(Gtk.Application):
def __init__(self):
Gtk.Application.__init__(self,
application_id="org.example.Foo",
flags=Gio.ApplicationFlags.FLAGS_NONE)
prg = Program()
sys.exit(prg.run(sys.argv));
this will actually warn you that you haven't implemented the GApplication::activate virtual function, which can be achieved by overriding the do_activate virtual method in your Program class:
class Program(Gtk.Application):
def __init__(self):
Gtk.Application.__init__(self,
application_id="org.example.Foo",
flags=Gio.ApplicationFlags.FLAGS_NONE)
def do_activate(self):
print("Activated!")
this will print Activated! on the console, before quitting.

initializing python class globally?

I have two files, one of the test.py is
import new.py
class Test:
def __init__(self):
return
def run(self):
return 1
if __name__ == "__main__":
one=Test()
one.run()
and new.py
class New:
def __init__(self):
one.run()
New()
Now when i run python test.py I get this error,
Traceback (most recent call last):
File "test.py", line 1, in <module>
import new.py
File "/home/phanindra/Desktop/new.py", line 5, in <module>
New()
File "/home/phanindra/Desktop/new.py", line 3, in __init__
one.run()
NameError: global name 'one' is not defined
But I want to use this instance of one in my New!!
Can I do this??
edit:
I want to access the variable in test.py in new.py to do some process and give them back to test.py. Isn't this possible?
If you want your New class to use the instance of Test you created, you have to pass it in as part of the constructor.
new.py
class New:
def __init__(self, one):
one.run()
test.py
import new
class Test:
def __init__(self):
return
def run(self):
return 1
if __name__ == "__main__":
one=Test()
two = new.New(one);
Playing around with globals is a great way to break your code without realizing how you did it. It is better to explicitly pass in the reference you want to use.
No, you can't. The closest you can get is to pass the thing you need in to the constructor:
class New(object):
def __init__(self, one):
one.run()
one is defined inside the if __name__=='__main__' block.
Consequently, one will get defined only if test.py is run as a script (rather than imported).
For the module new to access one from the test module, you'll need to pull one out of the if __name__ block:
test.py:
class Test:
def __init__(self):
return
def run(self):
return 1
one=Test()
if __name__ == "__main__":
one.run()
Then access one by the qualified name test.one:
new.py:
import test
class New:
def __init__(self):
test.one.run()
New()

Python Cmd module, subclassing issue

I'm trying to work out what's not working in this code:
#!/usr/bin/python
import cmd
class My_class (cmd.Cmd):
"""docstring for Twitter_handler"""
def __init__(self):
super(My_class, self).__init__()
if __name__ == '__main__':
my_handler = My_class()
Here's the error I get
Traceback (most recent call last):
File "main.py", line 12, in <module>
my_handler = My_class()
File "main.py", line 9, in __init__
super(My_class, self).__init__()
TypeError: super() argument 1 must be type, not classobj
If I change the superclass of "My_class" to an object it works fine. Where am I going wrong?
super() only works for new-style classes
cmd.Cmd is not a new style class in Python 2.5, 2.6, 2.7.
Note that your code does not raise an exception in Python 3.0.
So if super() doesn't work use :
import cmd
class My_class(cmd.Cmd):
def __init__(self):
cmd.Cmd.__init__(self)
You can still use super() if your MyClass extends object. This works even though the cmd.Cmd module is not a new-style class. Like this:
#!/usr/bin/python
import cmd
class My_class (cmd.Cmd, object):
"""docstring for Twitter_handler"""
def __init__(self):
super(My_class, self).__init__()
if __name__ == '__main__':
my_handler = My_class()

Categories

Resources