AttributeError: 'Player' Object has no attribute (attributes) [duplicate] - python

If your question was closed as a duplicate of this, it is because you had a code sample including something along the lines of either:
class Example:
def __int__(self, parameter):
self.attribute = parameter
or:
class Example:
def _init_(self, parameter):
self.attribute = parameter
When you subsequently attempt to create an instance of the class, an error occurs:
>>> Example("an argument")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Example() takes no arguments
Alternately, instances of the class seem to be missing attributes:
>>> class Example:
... def __int__(self): # or _init_
... self.attribute = 'value'
>>> Example().attribute
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Example' object has no attribute 'attribute'
You might also wonder: what do these exception messages mean, and how do they relate to the problem? Why didn't a problem occur earlier, for example, with the class definition itself? How else might the problem manifest? How can I guard against this problem in the future?
This is an artificial canonical duplicate created specifically to head off two of the most common typographical errors in code written by new Python programmers. While questions caused by a typo are normally closed for that reason, there are some useful things to explain in this case, and having a duplicate target allows for closing questions faster. I have tried to design the question to be easy to search for.

This is because the code has a simple typographical error: the method should instead be named __init__ - note the spelling, and note that there are two underscores on each side.
What do the exception messages mean, and how do they relate to the problem?
As one might guess, a TypeError is an Error that has to do with the Type of something. In this case, the meaning is a bit strained: Python also uses this error type for function calls where the arguments (the things you put in between () in order to call a function, class constructor or other "callable") cannot be properly assigned to the parameters (the things you put between () when writing a function using the def syntax).
In the examples where a TypeError occurs, the class constructor for Example does not take arguments. Why? Because it is using the base object constructor, which does not take arguments. That is just following the normal rules of inheritance: there is no __init__ defined locally, so the one from the superclass - in this case, object - is used.
Similarly, an AttributeError is an Error that has to do with the Attributes of something. This is quite straightforward: the instance of Example doesn't have any .attribute attribute, because the constructor (which, again, comes from object due to the typo) did not set one.
Why didn't a problem occur earlier, for example, with the class definition itself?
Because the method with a wrongly typed name is still syntactically valid. Only syntax errors (reported as SyntaxError; yes, it's an exception, and yes, there are valid uses for it in real programs) can be caught before the code runs. Python does not assign any special meaning to methods named _init_ (with one underscore on each side), so it does not care what the parameters are. While __int__ is used for converting instances of the class to integer, and shouldn't have any parameters besides self, it is still syntactically valid.
Your IDE might be able to warn you about an __int__ method that takes suspicious parameters (i.e., anything besides self). However, a) that doesn't completely solve the problem (see below), and b) the IDE might have helped you get it wrong in the first place (by making a bad autocomplete suggestion).
The _init_ typo seems to be much less common nowadays. My guess is that people used to do this after reading example code out of books with poor typesetting.
How else might the problem manifest?
In the case where an instance is successfully created (but not properly initialized), any kind of problem could potentially happen later (depending on why proper initialization was needed). For example:
BOMB_IS_SET = True
class DefusalExpert():
def __int__(self):
global BOMB_IS_SET
BOMB_IS_SET = False
def congratulate(self):
global BOMB_IS_SET
if BOMB_IS_SET:
raise RuntimeError("everything blew up, gg")
else:
print("hooray!")
If you intend for the class to be convertible to integer and also wrote __int__ deliberately, the last one will take precedence:
class LoneliestNumber:
def __int__(self):
return 1
def __int__(self): # was supposed to be __init__
self.two = "can be as bad"
>>> int(LoneliestNumber())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __int__ returned non-int (type NoneType)
(Note that __int__ will not be used implicitly to convert instances of the class to an index for a list or tuple. That's done by __index__.)
How might I guard against the problem in the future?
There is no magic bullet. I find it helps a little to have the convention of always putting __init__ (and/or __new__) as the first method in a class, if the class needs one. However, there is no substitute for proofreading, or for training.

Related

Why isn't my class initialized by "def __int__" or "def _init_"? Why do I get a "takes no arguments" TypeError, or an AttributeError?

If your question was closed as a duplicate of this, it is because you had a code sample including something along the lines of either:
class Example:
def __int__(self, parameter):
self.attribute = parameter
or:
class Example:
def _init_(self, parameter):
self.attribute = parameter
When you subsequently attempt to create an instance of the class, an error occurs:
>>> Example("an argument")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Example() takes no arguments
Alternately, instances of the class seem to be missing attributes:
>>> class Example:
... def __int__(self): # or _init_
... self.attribute = 'value'
>>> Example().attribute
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Example' object has no attribute 'attribute'
You might also wonder: what do these exception messages mean, and how do they relate to the problem? Why didn't a problem occur earlier, for example, with the class definition itself? How else might the problem manifest? How can I guard against this problem in the future?
This is an artificial canonical duplicate created specifically to head off two of the most common typographical errors in code written by new Python programmers. While questions caused by a typo are normally closed for that reason, there are some useful things to explain in this case, and having a duplicate target allows for closing questions faster. I have tried to design the question to be easy to search for.
This is because the code has a simple typographical error: the method should instead be named __init__ - note the spelling, and note that there are two underscores on each side.
What do the exception messages mean, and how do they relate to the problem?
As one might guess, a TypeError is an Error that has to do with the Type of something. In this case, the meaning is a bit strained: Python also uses this error type for function calls where the arguments (the things you put in between () in order to call a function, class constructor or other "callable") cannot be properly assigned to the parameters (the things you put between () when writing a function using the def syntax).
In the examples where a TypeError occurs, the class constructor for Example does not take arguments. Why? Because it is using the base object constructor, which does not take arguments. That is just following the normal rules of inheritance: there is no __init__ defined locally, so the one from the superclass - in this case, object - is used.
Similarly, an AttributeError is an Error that has to do with the Attributes of something. This is quite straightforward: the instance of Example doesn't have any .attribute attribute, because the constructor (which, again, comes from object due to the typo) did not set one.
Why didn't a problem occur earlier, for example, with the class definition itself?
Because the method with a wrongly typed name is still syntactically valid. Only syntax errors (reported as SyntaxError; yes, it's an exception, and yes, there are valid uses for it in real programs) can be caught before the code runs. Python does not assign any special meaning to methods named _init_ (with one underscore on each side), so it does not care what the parameters are. While __int__ is used for converting instances of the class to integer, and shouldn't have any parameters besides self, it is still syntactically valid.
Your IDE might be able to warn you about an __int__ method that takes suspicious parameters (i.e., anything besides self). However, a) that doesn't completely solve the problem (see below), and b) the IDE might have helped you get it wrong in the first place (by making a bad autocomplete suggestion).
The _init_ typo seems to be much less common nowadays. My guess is that people used to do this after reading example code out of books with poor typesetting.
How else might the problem manifest?
In the case where an instance is successfully created (but not properly initialized), any kind of problem could potentially happen later (depending on why proper initialization was needed). For example:
BOMB_IS_SET = True
class DefusalExpert():
def __int__(self):
global BOMB_IS_SET
BOMB_IS_SET = False
def congratulate(self):
global BOMB_IS_SET
if BOMB_IS_SET:
raise RuntimeError("everything blew up, gg")
else:
print("hooray!")
If you intend for the class to be convertible to integer and also wrote __int__ deliberately, the last one will take precedence:
class LoneliestNumber:
def __int__(self):
return 1
def __int__(self): # was supposed to be __init__
self.two = "can be as bad"
>>> int(LoneliestNumber())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __int__ returned non-int (type NoneType)
(Note that __int__ will not be used implicitly to convert instances of the class to an index for a list or tuple. That's done by __index__.)
How might I guard against the problem in the future?
There is no magic bullet. I find it helps a little to have the convention of always putting __init__ (and/or __new__) as the first method in a class, if the class needs one. However, there is no substitute for proofreading, or for training.

How to pass argument to a python decorator [duplicate]

This question already has answers here:
Decorators with parameters?
(23 answers)
Closed 3 years ago.
I am going to write a function decorator that takes an argument and returns a decorator that can be used to control the type of the argument to a one-argument function. I expect a raising error happens in case the passed argument be in a wrong type.
def typecontrol(num_type):
def wrapper_function(num):
if isinstance(num, num_type):
return num
else:
raise TypeError
return wrapper_function
#typecontrol(float)
def myfunc(num):
print(num)
I expect for example, myfunc(9.123) should print 9.123 and myfunc(9) should raise an error. But it always raises type error.
typecontrol will be a function that returns the decorator, not the decorator itself. You need an extra nested function:
def typecontrol(num_type):
def decorator(f):
def wrapper_function(num):
if isinstance(num, num_type):
f(num)
else:
raise TypeError
return wrapper_function
return decorator
#typecontrol(float)
def myfunc(num):
print(num)
The wrapper function will take care of calling the wrapped function if the typecheck passes, rather than returning the typechecked argument.
In your code as written, num is actually the function you are decorating, so you are checking if a function is an instance of (in this case), float.
Some examples:
>>> myfunc(3.0)
3.0
>>> myfunc("foo")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "tmp.py", line 7, in wrapper_function
raise TypeError
TypeError
As others have commented, a good explanation on writing decorators with arguments is found here.
However, it seems like you want to enforce types (I've gone down a similar rabbit hole before in Python) so depending on your use case would I possibly recommend two options:
If you want to make sure that your program is typed correctly prior to runtime, use the mypy static type checker.
If you need to parse/validate input values at runtime, I would highly suggest the pydantic package. It allows you to create "struct-like" objects (similar to a NamedTuple, or a dataclass) that will enforce runtime type checks and will appropriately coerce the input at runtime using Python 3.6+ type hints. Documentation and some helpful examples can be found here.
Depending on your use case, I hope either of these two help!

Does callable(obj) make an attempt to call?

I am exploring an API, and using the following to see what methods are available without searching through all attributes by eye with dir():
methods = [m for m in dir(kt) if callable(getattr(kt, m))]
which throws an exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Python/2.7/site-packages/soco/core.py", line 103, in inner_function
raise SoCoSlaveException(message)
soco.exceptions.SoCoSlaveException: The method or property "cross_fade" can only be called/used on the coordinator in a group
Ok, so I can't use cross_fade, that's fine. But I didn't try to call it, I was just trying to find out if I could.
I would have thought that callable() would be able to check using something similar to type(), but it seems like it's attempting to make a call and only catching certain types of exceptions.
I get the same exception when I tried type(kt.cross_fade), and when I just try >>> kt.cross_fade in the terminal.
So I guess there are two questions here: Does callable make an attempt to call? And, what can cause a method to "exist" but be completely unavailable?
callable doesn't attempt to call the object. It only checks that the object has an implementation of the call operator.
The exception is occurring in the attempt to retrieve the attribute in the first place. Attribute access can be overridden to do just about anything in Python, and the cross_fade attribute of this object is implemented as a property with an only_on_master decorator on the getter that raises an exception if you try to retrieve the attribute on a slave.
If we look at the source code, we'll see that cross_fade is actually a property:
#property
#only_on_master # Only for symmetry with the setter
def cross_fade(self):
"""The speaker's cross fade state.
True if enabled, False otherwise
"""
# ...
In turn, the getter is wrapped into only_on_master which is where the exception is raised.

Django-Monitor - get_model() takes at most 3 arguments (4 given)

I have been trying to find a way to moderate items going into the database so that a super user must approve before things are displayed. I found that Django-monitor manages to do pretty much all of that, I have been reading and following the documentation (here) and whenever I call django_monitor.nq(model_name) I get an error saying:
get_model takes at most 3 arguments (4 given)
I don't understand what is causing this problem and have been unable to find anything to help solve it.
That looks like a lib problem. if you are certain that it is caused on that line, then the lib's work is getting the error. I doubt that it's a lib error, so a full traceback would help a lot, and the models declaration as well.
Also, see if your django version is supported by the lib.
By the way, that error is caused when you call a function with too many arguments.
imagine that you have a class
class Foo(object):
def __init__(self, other):
self.other=other
calling:
>>> Foo(1)
<Foo object at 0x7f27566f90d0>
>>> Foo(1,2)
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: __init__() takes exactly 2 arguments (3 given)
Foo(1) works because the class's init takes 2 arguments(self and other)
It seems like it's incompatible with your django version. Looking at the repo source it seems like it was fixed:
try:
registered_model = get_model(
model._meta.app_label, model._meta.object_name, False, False
)
except TypeError:
# Django versions prior to 1.4 accept 3 params to get_model.
registered_model = get_model(
model._meta.app_label, model._meta.object_name, False
)
Unless the error raised now is not a TypeError.
get_model() was changed in 1.7 as explained in the release notes:
The app registry has preserved some features of the old app cache.
Even though the app cache was a private API, obsolete methods and
arguments will be removed through a standard deprecation path, with
the exception of the following changes that take effect immediately:
[...]
The only_installed argument of get_model and get_models no longer exists, nor does the seed_cache argument of get_model.
Since django-monitor tries to pass at least one of these arguments to get_model(), it is incompatible with Django 1.7+. It only accepts the app_label and model_name arguments.

Missing 1 required positional argument

I am as green as it gets when it comes to programming but have been making progress. My mind however still needs to fully understand what is happening.
class classname:
def createname(self, name):
self.name = name;
def displayname(self):
return self.name;
def saying(self):
print("Hello %s" % self.name);
first = classname;
second = classname;
first.createname("Bobby");
Error:
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
first.createname("Bobby")
TypeError: createname() missing 1 required positional argument: 'name'
The error tells me that I need 1 more argument in the name, so I must be going wrong there, but I already tried something like this:
first.createname("bobby", "timmy");
I also rule out the fact that it would be the def createname(self, name), because self is or should be alone and not included? So I do not really understand what is going on.
You have not actually created an object yet.
For instance, you would want to write:
first = classname()
instead of just
first = classname
At the moment, how you wrote it, first is pointing to a class. E.g., if you ask what first is, you'd get:
<class '__main__.classname'>
However, after instantiating it (by simply adding the () at the end), you'd see that first is now:
<__main__.classname object at 0x101cfa3c8>
The important distinction here is that your call set first as a class, whereas mine set it as an object.
Think about it like this: A class is to an object as humankind is to you, or as canine is to Lassie.
You set it as "canine", whereas you wanted to set it as "Lassie".
Note: you also usually want to initialize your objects. For that, you place an __init__ method in your class.

Categories

Resources