Quando você usa o . você está dizendo ao compilador que randrange é um módulo de random, mas randrange é uma função, e random é um módulo não um pacote. Entenda pacote como uma pasta cheia de módulos, módulos são os arquivos .py. Pacotes podem ter subpacotes dentro de si. Olhe abaixo um exemplo da documentação oficial do python sobre módulos:
sound/ Top-level package
__init__.py Initialize the sound package
formats/ Subpackage for file format conversions
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ Subpackage for sound effects
__init__.py
echo.py
surround.py
reverse.py
...
filters/ Subpackage for filters
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
O pacote SOUND tem dentro de si 3 subpacotes, FORMATS, EFFECTS e FILTERS. Cada subpacote tem diversos módulos. Para importar o módulo echo.py que está no subpacote effects, devemos usar:
import sound.effects.echo
Dizemos ao programa: Traga o arquivo echo.py da pasta effect que está na pasta sound. Fazendo dessa forma, toda vez que utilizarmos alguma função de echo.py, devemos referenciar todo o diretório manualmente, assim:
sound.effects.echo.função()
Para não precisar fazer isso, você utiliza "from import" aí só vai precisar colocar o nome do módulo:
from sound.effects import echo
echo.função()
Ou simplesmente use "import as" para criar um nome que deseja usar no lugar de echo
import sound.effects.echo as ec
ec.função()
Para que uma pasta seja considerada um PACOTE, deve existir em sua raiz, um arquivo __init__.py
, pode ser vazio, em branco, só precisa existir, crie um arquivo .txt em branco e o renomeie para __init__.py
(olhe a lista que coloquei acima, todas pastas contém o arquivo)
Para mais informações, leia a documentação do python, se não souber inglês basta selecionar o idioma no canto superior esquerdo da página, tem tradução para português:
https://docs.python.org/3/tutorial/modules.html#packages