When I create an ordinary object, like below, I can assign different variables to it that hasn’t been defined in the __init__() method:
class Test:
pass
test = Test()
test.Something = 0
but in the code below, I can't.
import pygame
pygame.init()
screen = pygame.display.set_mode()
print(type(screen))
red = (255, 0, 0)
blue = (0, 0, 255)
screen.turn = 0
while True:
if (screen.turn):
screen.fill(blue)
else:
screen.fill(red)
screen.turn = 1 - screen.turn
pygame.event.pump()
pygame.display.update()
Instead, an AttributeError exception is raised and the program gives the output below:
pygame 2.1.2 (SDL 2.0.18, Python 3.9.13)
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
File "/Users/armaho/Programs/Python/main.py", line 10, in <module>
screen.turn = 0
AttributeError: 'pygame.Surface' object has no attribute 'turn'
<class 'pygame.Surface'>
Why is that?
Much of PyGame is written in C. The default object type does not have a namespace dictionary and does not allow python level set attribute. A python class written in C can implement a setattr call, but they usually don't. An extra namespace dict and the extra weight needed to support arbitrary attribute assignment is not usually necessary.
You can see the default object class in action
>>> o = object()
>>> o.turn = 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'turn'
Related
I am creating a universal text field that can be used in many python turtle projects. I am trying to create an instance of it but I get this error:
>>> import TextField
>>> tf = TextField('None', False)
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
tf = TextField('None', False)
TypeError: 'module' object is not callable
>>>
What in a module causes this type of error? I completely wrote this module and I'm getting an error creating an instance of it :( ... What do I need in this module to make it 'callable'? I have tried adding a def __call__(self): but that doesn't affect the problem at all, nor create any errors.
Here is the beginning of the script where the problem is most likely happening:
# Created by SUPERMECHM500 # repl.it
# Edited by cdlane # stackoverflow.com
class TextField:
TextFieldBorderColor = '#0019fc'
TextFieldBGColor = '#000000'
TextFieldTextColor = '#ffffff'
ShiftedDigits = {
'1':'!',
'2':'#',
'3':'#',
'4':'$',
'5':'%',
'6':'^',
'7':'&',
'8':'*',
'9':'(',
'0':')'
}
def __init__(self, command, CanBeEmpty): # Ex. textField = TextField('Execute()', True)
self.CmdOnEnter = command
self.turtle = Turtle()
self.CanBeEmpty = CanBeEmpty
self.turtle.speed('fastest')
self.inp = []
self.FullOutput = ""
self.TextSeparation = 7
self.s = self.TextSeparation
self.key_shiftL = False
......
The module is not the class. If your class TextField is in a module called TextField, then it is referred to as TextField.TextField.
Or change your import to
from TextField import TextField
Getting started with python-sfml. This code
import sfml
window = sfml.RenderWindow(sfml.VideoMode(640, 480), "FooBar")
try:
texture = sfml.Texture.from_file("brick_002.jpg")
sprite = sfml.Sprite(texture)
font = sfml.Font.from_file("arial.ttf")
text = sfml.Text("Math Rocks!")
except IOError:
exit(1)
while window.is_open:
for event in window.events:
if type(event) is sfml.CloseEvent:
window.close()
window.clear()
window.draw(sprite)
window.draw(text)
window.display()
and getting this mistake:
Traceback (most recent call last):
File "sfml.py", line 1, in <module>
import sfml
File "/home/montreal/projects/foo/sfml/sfml.py", line 4, in <module>
window = sfml.RenderWindow(sfml.VideoMode(640, 480), "FooBar")
AttributeError: 'module' object has no attribute 'RenderWindow'
But in interpreter everyting works fine (I can create window, add texture and close it). What can be wrong?
I'm using BeautifulSoup to do some crawling, and want to chain find calls, for example:
soup.find('div', class_="class1").find('div', class_="class2").find('div', class_="class3")
Of course, this breaks whenever one of the divs cannot be found, throwing an
AttributeError: 'NoneType' object has no attribute 'find'
Is there a way to modify NoneType to add a find method such as
class NoneType:
def find(*args):
return None
so that I can do something like
thing = soup.find('div', class_="class1").find('div', class_="class2").find('div', class_="class3")
if thing:
do more stuff
instead of
thing1 = soup.find('div', class_="class1")
if thing1:
thing2 = thing1.find('div', class_="class2")
if thing2:
thing3 = thing2.find('div', class_="class3")
etc.
I think I might be able to do something similar by using a parser with XPath capabilities, but the question is not specific to this use case and is more about modifying/overriding built in classes.
Why not use a try/except statement instead (since you cannot modify NoneType)?
try:
thing = soup.find('div', class_="class1").find('div', class_="class2").find('div', class_="class3")
do more stuff
except AttributeError:
thing = None # if you need to do more with thing
You can't modify builtin class such as NoneType or str:
>>> nt = type(None)
>>> nt.bla = 23
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't set attributes of built-in/extension type 'NoneType'
For some of them (eg str), you can inherit from:
>>> class bla(str):
... def toto(self): return 1
>>> bla('2123').toto()
1
It's not possible with NoneType. And it won't help you either:
>>> class myNoneType(nt):
... def find(self): return 1
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
type 'NoneType' is not an acceptable base type
You cannot modify the class and the real question is why you would try? NoneType means there is no data there so when you attempt a .find() on that type even if it did exist you would only get null or no values from it. I would reccomend something like this.
try:
var = soup.find('div', class_="class1").find('div', class_="class2").find('div', class_="class3")
except AttributeError:
do something else instead or message saying there was no div
You can't inherit from None:
>>> class Noneish(type(None)):
... pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: type 'NoneType' is not an acceptable base type
An approach might be to have a
class FindCaller(object):
def __init__(self, *a, **k):
self.a = a
self.k = k
def __call__(self, obj):
return obj.find(*self.a, **self.k)
def callchain(root, *fcs):
for fc in fcs:
root = fc(root)
if root is None: return
return root
and then do
thing = callchain(soup,
FindCaller('div', class_="class1"),
FindCaller('div', class_="class2"),
FindCaller('div', class_="class3"),
)
You can't. For good reasons...
In fact, NoneType is even less accessible than other built-in types:
type(None).foo = lambda x: x
# ---------------------------------------------------------------------------
# TypeError Traceback (most recent call last)
# <ipython-input-12-61bbde54e51b> in <module>()
# ----> 1 type(None).foo = lambda x: x
# TypeError: can't set attributes of built-in/extension type 'NoneType'
NoneType.foo = lambda x: x
# ---------------------------------------------------------------------------
# NameError Traceback (most recent call last)
# <ipython-input-13-22af1ed98023> in <module>()
# ----> 1 NoneType.foo = lambda x: x
# NameError: name 'NoneType' is not defined
int.foo = lambda x: x
# ---------------------------------------------------------------------------
# TypeError Traceback (most recent call last)
# <ipython-input-14-c46c4e33b8cc> in <module>()
# ----> 1 int.foo = lambda x: x
# TypeError: can't set attributes of built-in/extension type 'int'
As suggested above, use try: ... except AttributeError: clause.
i'm trying to load a binary file with pickle that has a record in a list, like so
import pickle
class player_energy_usage():
def __init__(self):
self.weapons = 25
elf.shields = 25
self.life_support = 25
self.engines = 25
def p_eu_init():
global p_energy
p_energy = []
player_ship_energy = player_energy_usage()
p_energy.append(player_ship_energy)
pickle.dump(p_energy,open('p_energy.dat','wb'))
p_eu_init()
pickle.load('rb'('p_energy.dat'))
print('Weapons are using {0}% of energy'.format(p_energy[0].weapons))
print('Shields are using {0}% of energy'.format(p_energy[0].shields))
print('Life Support is using {0}% of energy'.format(p_energy[0].life_support))
print('Engines is using {0}% of energy'.format(p_energy[0].engines))
However i get a type error,
Traceback (most recent call last):
File "E:/Python texted based game/Tests/file loading test.py", line 18, in <module>
pickle.load('rb'('p_energy.dat'))
TypeError: 'str' object is not callable
thanks for the help.
That is not the correct syntax. It should be instead:
p_energy = pickle.load(open('p_energy.dat', 'rb'))
What you're actually doing is:
'rb'('p_energy.dat') is trying to call the str object 'rb' with an argument of 'p_energy.dat', which is why you get the error 'str' object is not callable.
I've been trying to get my Tkinter wrapper (specialised to make a game out of) to work, but it keeps throwing up an error when it tries to draw a rectangle.
Traceback:
Traceback (most recent call last):
File "C:\Users\William\Dropbox\IT\Thor\test.py", line 7, in <module>
aRectangle = thorElements.GameElement(pling,rectangleTup=(True,295,195,305,205,"blue"))
File "C:\Users\William\Dropbox\IT\Thor\thorElements.py", line 79, in __init__
self.rectangle = self.area.drawRectangle(self)
File "C:\Python33\lib\tkinter\__init__.py", line 1867, in __getattr__
return getattr(self.tk, attr)
AttributeError: 'tkapp' object has no attribute 'drawRectangle'
The sections of the code that are relevant to the question,
class GameElement():
def __init__(self,area,rectangleTup=(False,12,12,32,32,"red")):
self.area = area
self.lineTup = lineTup #Tuple containing all the data needed to create a line
if self.lineTup[0] == True:
self.kind = "Line"
self.xPos = self.lineTup[1]
self.yPos = self.lineTup[2]
self.line = self.area.drawLine(self)
And here's the actual method that draws the rectangle onto the canvas (in the class that manages the Canvas widget), earlier in the same file:
class Area():
def drawLine(self,line):
topX = line.lineTup[1]
topY = line.lineTup[2]
botX = line.lineTup[3]
botY = line.lineTup[4]
colour = line.lineTup[5]
dashTuple = (line.lineTup[6][0],line.lineTup[6][1])
return self.canvas.create_line(topX,topY,botX,botY,fill=colour,dash=dashTuple)
print("Drew Line")
All input is greatly appreciated.
The error message is meant to be self explanatory. When it says AttributeError: 'tkapp' object has no attribute 'drawRectangle', it means that you are trying to do tkapp.drawRectangle or tkapp.drawRectangle(...), but tkapp doesn't have an attribute or method named drawRectangle.
Since your code doesn't show where you create tkapp or how you created it, or where you call drawRectangle, it's impossible for us to know what the root of the problem is. Most likely it's one of the following:
tkapp isn't what you think it is
you have a typo, and meant to call drawLine rather than drawRectangle,
you intended to implement drawRectangle but didn't