I am looking at a snippet of code and I just don't understand how it works:
import pygame, sys
from pygame.locals import *
on the first line pygame is imported, and on the second line, all the methods of a subset of pygame is invoked. If the first line imports all of pygame, why do we have to specifically import a subset of the module again? Why doesn't a mere import pygame do the job in the first place?
A mere import pygame would suffice, but the author wanted to have a shorthand access to the constants of pygame. For example, instead of:
import pygame
...
resolution = pygame.locals.TIMER_RESOLUTION
it may be sometimes preferable to have
import pygame
from pygame.locals import *
...
resolution = TIMER_RESOLUTION
Note that you should still import pygame itself to be able to access to other methods/properties (other than pygame.locals.) of pygame.
The idea is that you can call all the functions in pygame.locals without using pygame.locals.someFunction, but instead someFunction.
Related
This question already has answers here:
Difference between "import X" and "from X import *"? [duplicate]
(7 answers)
Use 'import module' or 'from module import'?
(23 answers)
Closed 7 months ago.
I am trying to use a book on python, and I understand that from turtle import * imports everything into the current namespace while import turtle just brings the module in so it can be called as a class. When I try the latter, though, it breaks.
>>> import turtle
>>> t = turtle.pen()
>>> t.pen.forward(10)
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
t.pen.forward(10)
AttributeError: 'dict' object has no attribute 'pen
However, using from turtle import*, assigning pen to an object and typing command forward works fine. This is not what the book says to do, but it is the only thing that works. What is happening?
If the books says something like:
import turtle
t = turtle.pen()
t.forward(10)
then it's probably a typo for:
import turtle
t = turtle.Pen()
t.forward(10)
where Pen is a synonym for Turtle -- we've seen that problem here before. (Lowercase pen() is a utility function that's rarely used except in error.)
I understand that from turtle import * imports everything into the
current namespace while import turtle just brings the module in so it
can be called as a class
My recommendation: use neither. Instead do:
from turtle import Screen, Turtle
screen = Screen()
turtle = Turtle()
turtle.forward(10)
# ...
screen.exitonclick()
The reason is that Python turtle exposes two programming interfaces, a functional one (for beginners) and an object-oriented one. (The functional interface is derived from the object-oriented one at library load time.) Using either is fine but using both at the same time leads to confusion and bugs. The above import gives access to the object-oriented interface and blocks the funcitonal one.
I am currently learning Python 3.xx (3,8 currently to be more specific) as first language and am seeing all the time something like
from tkinter import *
from tkinter import font
Now my question here is...:
when you import from tkiner *(therefore all) why do you import again certain elements? Should it not be included in all ( * )?
Thank you in advance for your time and effort spent on answering my question and have a wonderfull day.
The second line will import tkinter.font, which is a submodule.
import * won't import submodules.
>>> from tkinter import *
>>> font
>>> from tkinter import font
>>> font
<module 'tkinter.font' from 'lib/python3.7/tkinter/font.py'>
Another case where * would not import everything is when the module has an __all__ attribute. (Search for "public names" in the documentation here.)
The code below works perfectly, however, PyCharm complains about syntax error in forward(100)
#!/usr/bin/python
from turtle import *
forward(100)
done()
Since turtle is a stanrd library I don't think that I need to do additional configuration, am I right?
The forward() function is made available for importing by specifying __all__ in the turtle module, relevant part from the source code:
_tg_turtle_functions = [..., 'forward', ...]
__all__ = (_tg_classes + _tg_screen_functions + _tg_turtle_functions +
_tg_utilities + _math_functions)
Currently, pycharm cannot see objects being listed in module's __all__ list and, therefore, marks them as an unresolved reference. There is an open issue in it's bugtracker:
Make function from method: update __all__ if existing for starred import usage
See also: Can someone explain __all__ in Python?
FYI, you can add the noinspection comment to tell Pycharm not to mark it as an unresolved reference:
from turtle import *
#noinspection PyUnresolvedReferences
forward(100)
done()
Or, disable the inspection for a specific scope.
And, of course, strictly speaking, you should follow PEP8 and avoid wildcard imports:
import turtle
turtle.forward(100)
turtle.done()
Another solution would be to explicitly create a Turtle object. Then autocomplete works just as it should and everything is a bit more explicit.
import turtle
t = turtle.Turtle()
t.left(100)
t.forward(100)
turtle.done()
or
from turtle import Turtle
t = Turtle()
I'm fairly new to programming in general and I just started using python to try and make a simple game using pygame. If I run the following code in the Python IDLE shell it works fine but if I use Pyscripter I get the error:
SyntaxError: import * only allowed at module level
I really like using Pyscripter because so far it has made learning the syntax much easier but now I don't understand what is wrong. Any help would be great. Thanks.
import pygame, sys
from pygame.locals import *
pygame.init()
DISPLAYSURF = pygame.display.set_mode((400,300),0,32)
pygame.display.set_caption('Hello World!')
while True: #main game loop
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
The problem is when you execute from pygame.locals import * you are accessing all from a file, not a module. When you do something like from pygame import *, it should work. It is just that you can only use import * at the module level
I know it is a stupid question but I am just starting to learn python and i don't have good knowledge of python. My question is what is the difference between
from Tkinter import *
and
import Tkinter as tk
?Why can't i just write
import Tkinter
Could anyone spare a few mins to enlighten me?
from Tkinter import * imports every exposed object in Tkinter into your current namespace.
import Tkinter imports the "namespace" Tkinter in your namespace and
import Tkinter as tk does the same, but "renames" it locally to 'tk' to save you typing
let's say we have a module foo, containing the classes A, B, and C.
Then import foo gives you access to foo.A, foo.B, and foo.C.
When you do import foo as x you have access to those too, but under the names x.A, x.B, and x.C.
from foo import * will import A, B, and C directly in your current namespace, so you can access them with A, B, and C.
There is also from foo import A, C wich will import A and C, but not B into your current namespace.
You can also do from foo import B as Bar, which will make B available under the name Bar (in your current namespace).
So generally: when you want only one object of a module, you do from module import object or from module import object as whatiwantittocall.
When you want some modules functionality, you do import module, or import module as shortname to save you typing.
from module import * is discouraged, as you may accidentally shadow ("override") names, and may lose track which objects belong to wich module.
You can certainly use
import Tkinter
However, if you do that, you'd have to prefix every single Tk class name you use with Tkinter..
This is rather inconvenient.
On the other hand, the following:
import Tkinter as tk
sidesteps the problem by only requiring you to type tk. instead of Tkinter..
As to:
from Tkinter import *
it is generally a bad idea, for reasons discussed in Should wildcard import be avoided?
Writing:
from tkinter import *
results in importing everything that exists in tkinter module
Writing:
import tkinter
results in importing tkinter module but if you do so, in order to be able to call any method you will have to use:
tkinter.function_name()