Python multithreading error "group argument must be None for now" - multithreading

I have created a class "MyThread" which inherits "Thread" class and one other class "Main" which is again defined in my project. When I try to instantiate the object of "MyThread" class, it gives the exception "group argument must be None for now". Below is the code:
myThreadObject1 = myThread.MyThread("Thread 1",True)
class MyThread (threading.Thread,main.Main):
def __init__(self,name,flag):
try:
#threading.Thread.__init__(self)
super(MyThread,self).__init__(self)
self.threadName = name
self.flag = flag
except Exception as e:
print(str(e))
exit(1)

Go to python folder and find "threading.py". After that commit assert line as shown below
#assert group is None, "group argument must be None for now"
Note: You must be admin.

You've called the thread constructor incorrectly, it should be
super(MyThread, self).__init__()
The call to init already gets self sent to it, so when you provide it again it sets another argument in the Thread class constructor and things get confused.

Related

How to deal with type checking for optionally None variable, Python3?

In the example below. The init method of MyClass defined the attribute self._user has optionally the type of UserInput and is initialized as None. The actual user input should be provided by the method set_user. For some practical reason, the user input cannot be provided to the method __init__. After giving user input, other methods method_1 and method_2 can be called.
Question to professional Python programmers: do I really need to add assert ... not None in every method that uses self._user? Otherwise, VS Code Pylance type checking will complain that self._user might be None.
However, I tried the same code in PyCharm with its built-in type checking. This issue is not raised there.
And as professional Python programmers, do you prefer the Pylance type checking in VS Code, or the built-in type checking in PyCharm?
Thanks in advance.
class UserInput:
name: str
age: int
class MyClass:
def __init__(self):
self._user: UserInput | None = None
def set_user(self, user: UserInput): # This method should be called before calling any methods.
self._user = user
def method_1(self):
assert self._user is not None # do I actually need it
# do something using self._user, for example return its age.
return self._user.age # Will get warning without the assert above.
def method_2(self):
assert self._user is not None # do I actually need it
# do something using self._user, for example return its name.
I think it's safest and cleanest if you keep the asserts in. After all, it is up to the user of your class in which order he calls the instance methods. Therefore, you cannot guarantee that self._user is not None.
I think it's bad practice to use assert in production code. When things go wrong, you get lots of AssertionError, but you don't have any context about why that assertion is being made.
Instead I would catch the issue early, and not handle it later. If set_user() should be called earlier, I'd be tempted to put the user in the __init__ method, but the same principle applies.
#dataclass
class UserInput:
name: str
age: int
class NoUserException(TypeError):
pass
class MyClass:
# Or this could be in the __init__ method
def set_user(self, user: UserInput | None):
if not user:
raise NoUserException()
self._user: user
def method_1(self):
# do something using self._user, for example return its age.
return self._user.age
def method_2(self):
# do something using self._user, for example return its name.
return self._user.name
You already stated that set_user will be called first, so when that happens you'll get a NoUserException if the user is None.
But I'd be tempted to not even do that. If I were writing this, I'd have no NoneType checking in MyClass, and instead not call set_user if the user was None.
m = MyClass()
user = ...
if user:
m.set_user(user)
... # anything else with `m`
else:
# here is where you would get an error

Visual Studio Community 2019 + Python

I made the following simple class in Visual studio community edition:
class Check(object):
def __init__(self):
self.t = 5
but when run
from Check import Check
try:
print(Check.t)
except Exception as Err:
print(str(Err))
or
import Check
try:
print(Check.t)
except Exception as Err:
print(str(Err))
I get the error of:
The object 'Check' has no attribute 't'
It is also weird because the keyword 'self' is not shown as Python keyword or Buildin func.
You've gotta instantiate the Object of Check before being able to access it.
This can be done by the following
from Check import Check
try:
print(Check().t)
except Exception as Err:
print(str(Err))
When you try to call Check.t it's trying to access the class element 't' which is non existent.
The information regarding visual studio community is redundant here.
The problem lies with how you're defining and calling your class.
You've created a class(the blueprint) but haven't created any instance (actual object) while calling the attribute (variable t).
Let's say you have a module named check.py where you've defined your simple class.
# check.py
class Check:
def __init__(self):
self.t = 5
Now import the class Check from module check.py
from check import Check
# create an instance of the class
ins = Check()
# access and print the attribute
try:
att = ins.t
print(att)
except Exception as err:
print(str(err))

How to use parent class to enforce subclasses to set value to an attribute?

I want the Parent class to have a checking mechanism to ensure all its subclasses to set an actual value to the attribute name. I found something here.
class Parent(object):
#name = None
def __init__(self):
if self.name == None:
raise NotImplementedError('Subclasses must define name')
class Child1(Parent):
pass
class Child2(Parent):
name = 'test'
class Child3(Parent):
def __init__(self):
self.name = 'test'
class Child4(Parent):
def __init__(self):
pass
#obj1 = Child1() # Expected output: NotImplementedError: Subclasses must define bar
obj2 = Child2()
obj3 = Child3()
obj4 = Child4() # I want the NotImplementedError is raised here as well, but it doesn't
The problem is as long as there is an __init__ method in the subclass, it overwrites the Parent class and the raise NotImplementedError is no longer in effect.
My current working solution is:
class Child5(Parent):
def __init__(self):
self.name = 'test'
super().__init__()
obj5 = Child5()
which seems to work, but I wonder if it's a proper implementation, or if it may have some hidden pitfalls, and also if I should learn to use/implement #abstractproperty instead of this solution?
Here, you need to understand when you parent class constructor gets called. Note that while creating child class objects, if child class has a constructor it is called by default. It is up to us whether we want to call parent class constructor as well and this shall be done by us. However if child class doesn't have a constructor, then the base class constructor is called.
So with your Child1(), parent constructor is called by default so it raises the exception.
In your Child2() as well parent constructor is called. However do note here that name variable is static and can even be accessed as Child2.name. And thus no exception is raised.
Your Child3 class has a constructor has a constructor thus parent constructor is never called and thus check for presence of name is actually never made. So you do need to add following line to to child constructor.
super().__init__()
This call shall be made after declaring name if constructor defines name. And this is what you have done in your Child5 class.
For exactly the same reason as above, exception was not captured in Child4. Following will check this condition in Child4:
class Child4(Parent):
def __init__(self):
super().__init__()
You can check when constructor is being called, by simply adding a unique print statement(such as print(1), print(2), and so on) in each constructor (preferably at the beginning).

Python - can call same class twice(or more) in thread?

I don't very understand the classes logic in python but cannot answer on web.
I have create a class to generate person info:
class person:
def fristnameGen(gender):
...
def emailGen(firstname,surname):
...
i create a bot to call it like this:
from person import *
class bots:
def __init__(self):
self.person = person()
def createDB(self):
print(self.person.name)
#do something...
finally i call it by a button with thread
from bots import *
import threading
class Panel:
def __init__(self):
self.top = tk.Tk()
self.bot = bots()
self.buildUI()
def foo(self):
self.bot.createDB(self.stringPhone.get())
def threadTheAction(func, *args):
t = threading.Thread(target=func, args=args)
t.setDaemon(True)
t.start()
def buildUI(self):
Button = tk.Button(self.top, text ="Start", command = lambda :self.threadTheAction(self.foo))
I get this error:
TypeError: 'Panel' object is not callable
However, i call it directly, its work
Button = tk.Button(self.top, text ="Start", command = lambda :self.foo())
How to fix the error?
...
2. Moreover, i tried create p1 = person() and p2= person() and print it. Found p1 and p2 is a same person, i prefer each new a class have a new one. How to generate "new person" using classes?
Thank you
You seem to have a lot of confusion about Object Oriented Programming in Python. Some of your methods have self parameters and some do not, seemingly at random. That's the source of your current error.
The threadTheAction method in your Panel class is getting the Panel instance passed in as its first argument, but that's named func in the method (since you omitted self). The real function you're passing as an argument gets caught in the variable argument *args. When the thread tries unsuccessfully to call it, you get an exception. Adding self before func would fix the immediate problem:
def threadTheAction(self, func, *args):
I suspect if your code got further along, you'd run into other errors with other methods without self in their parameter lists. For instance, none of the methods you've shown in person are likely to work correctly.
As for your second question, you haven't shown enough of person to know what's happening, but you're probably doing instance variables wrong somehow. With no self parameter in the methods, that's almost inevitable (since you assign to self.whatever to set a whatever attribute on the current instance). If you need help squaring that away, I suggest you ask a separate question (Stack Overflow is best when each question is self-contained) and provide the full code for your person class.

trying to call a class, but keep getting message that says that "position takes no arguments

I have been working with classes however when ever I try to call an object within a class, I keep getting a message saying that the call takes no arguments. A simple example is in the following where I try to call a card, however it will not show. Do you have any idea as to what can be causing the issue?
class Card(object):
def _init_(self, symbol, rank):
self.symbol = symbol
self.rank = rank
def show(self):
print("{} of {}".format(self.rank, self.symbol))
card = Card("clubs", 6)
card.show(self)
The following is the error that appears:
card = Card("clubs", 6)
TypeError: Card() takes no arguments
You need to name the constructor method __init__, with two underscores on either side, not _init_.
As answered by #jwodder, you have to use __init__. Also while calling the show() you should call card.show().

Resources