10 минут кода: Расширяем возможности `pprint()`
Привет! Я покажу о свою реализацию функции pprint(). Это простая функция, которая помогает сделать вывод данных в консоль более читаемым. Когда у тебя есть сложные структуры, например, большие словари, списки или объекты pprint() «красиво» выводит их на экран. Функция также выводит на экран N строк текстовых файлов
pprint(dict)
pprint(list)
pprint(Object)
pprint('text.txt', max_lines=10)
и получить данные в «читабельном» виде.
сразу код функции:
import json
import csv
import pandas as pd
from pathlib import Path
from typing import Any
from pprint import pprint as pretty_print
def pprint(print_data: str | list | dict | Path | Any = None, depth: int = 4, max_lines: int = 10, *args, **kwargs) -> None:
""" Pretty prints the given data in a formatted way.
The function handles various data types and structures such as strings, dictionaries, lists, objects, and file paths.
It also supports reading and displaying data from CSV and XLS/XLSX files.
Args:
print_data (str | list | dict | Any, optional): The data to be printed. It can be a string, dictionary, list, object, or file path. Defaults to `None`.
depth (int, optional): The depth to which nested data structures will be printed. Defaults to 4.
max_lines (int, optional): Maximum number of lines to print from a file (CSV/XLS). Defaults to 10.
*args: Additional positional arguments passed to the print or pretty_print function.
**kwargs: Additional keyword arguments passed to the print or pretty_print function.
Returns:
None: The function prints the formatted output and does not return any value.
Example:
>>> pprint("/path/to/file.csv", max_lines=5)
>>> pprint("/path/to/file.xls", max_lines=3)
"""
if not print_data:
return
def _read_text_file(file_path: str | Path, max_lines: int) -> list | None:
"""Reads the content of a text file up to `max_lines` lines."""
path = Path(file_path)
if path.is_file():
try:
with path.open("r", encoding="utf-8") as file:
return [file.readline().strip() for _ in range(max_lines)]
except Exception as ex:
pretty_print(print_data)
return None
def _print_class_info(instance: Any, *args, **kwargs) -> None:
"""Prints class information including class name, methods, and properties."""
class_name = instance.__class__.__name__
class_bases = instance.__class__.__bases__
print(f"Class: {class_name}", *args, **kwargs)
if class_bases:
print([base.__name__ for base in class_bases], *args, **kwargs)
attributes_and_methods = dir(instance)
methods = []
properties = []
for attr in attributes_and_methods:
if not attr.startswith('__'):
try:
value = getattr(instance, attr)
except Exception:
value = "Error getting attribute"
if callable(value):
methods.append(f"{attr}()")
else:
properties.append(f"{attr} = {value}")
pretty_print("Methods:", *args, **kwargs)
for method in sorted(methods):
pretty_print(method, *args, **kwargs)
print("Properties:", *args, **kwargs)
for prop in sorted(properties):
pretty_print(prop, *args, **kwargs)
def _print_csv(file_path: str, max_lines: int) -> None:
"""Prints the first `max_lines` lines from a CSV file."""
try:
with open(file_path, newline='', encoding='utf-8') as csvfile:
reader = csv.reader(csvfile)
header = next(reader)
print(f"CSV Header: {header}")
for i, row in enumerate(reader, start=1):
print(f"Row {i}: {row}")
if i >= max_lines:
break
except Exception as ex:
pretty_print(print_data)
def _print_xls(file_path: str, max_lines: int) -> None:
"""Prints the first `max_lines` rows from an XLS/XLSX file."""
try:
df = pd.read_excel(file_path, nrows=max_lines)
print(df.head(max_lines).to_string(index=False))
except Exception as ex:
pretty_print(print_data)
def json_serializer(obj):
"""Custom handler for unsupported data types in JSON."""
if isinstance(obj, Path):
return str(obj)
# Check if it's a file path
if isinstance(print_data, str):
if Path(print_data).is_file():
file_extension = Path(print_data).suffix.lower()
if file_extension == '.csv':
_print_csv(print_data, max_lines)
elif file_extension in ['.xls', '.xlsx']:
_print_xls(print_data, max_lines)
elif file_extension == '.txt':
content = _read_text_file(print_data, max_lines)
if content:
for line in content:
print(line)
elif file_extension == '.json':
try:
with open(print_data, 'r', encoding='utf-8') as json_file:
json_data = json.load(json_file)
print(json.dumps(json_data, default=json_serializer, indent=4))
except Exception as ex:
pretty_print(print_data)
else:
pretty_print(print_data, *args, **kwargs)
else:
# If the data is not a file, pretty print or handle it as a class
try:
if isinstance(print_data, dict):
print(json.dumps(print_data, default=json_serializer, indent=4))
elif isinstance(print_data, list):
print("[")
for item in print_data:
print(f"\t{item} - {type(item)}")
print("]")
else:
print(print_data, *args, **kwargs)
if hasattr(print_data, '__class__'):
_print_class_info(print_data, *args, **kwargs)
except Exception as ex:
pretty_print(print_data)
код на github
Для запуска и проверки кода я сделал Интерактивный блокнот google colab
Как работает функция:
Печать строковых данных**: Если предоставленный аргумент является строкой, функция проверяет, представляет ли она путь к файлу. Если это так, функция считывает содержимое файла и выводит его. Если строка не является путем к файлу, функция просто выводит строку.
Печать списков**: Если аргумент является списком, функция преобразует все объекты `Path` в списке в строки и использует стандартную функцию `pprint` для форматирования списка.
Печать словарей**: Если аргумент является словарем, функция преобразует все объекты `Path` в строки, чтобы обеспечить корректную сериализацию в JSON. Затем она выводит словарь в формате JSON с отступами для повышения читаемости
Печать объектов**: Если аргумент является объектом, функция использует `pprint`, чтобы вывести объект вместе с дополнительной информацией о его классе, методах и свойствах. Функция выводит имя класса, его базовые классы и перечисляет методы и свойства объекта, упрощая анализ его структуры.
Вывод в консоль произвольное количество сток из тексовых файлов (txt, json,csv,xls)
Примеры.
Все примеры можно запускать в блокноте jupyter notebook https://colab.research.google.com/drive/1uBcZuMabkix2qpNJtNk...
Здеськраткое руководство как пользоваться блокнотом
Пример 1: Строка
pprint("Hello, World!")
Результат:
'Hello, World!'
Пример 2.1: Список
from pathlib import Path
example_list = [
"Hello, World!",
Path("C:/example/path"),
42,
{"key": "value"}
]
example_list_2 = [
"Python is fun!",
Path("/home/user/project"),
99,
{
"name": "Alice",
"age": 30,
"languages": ["Python", "JavaScript", "C++"]
}
]
pprint(example_list)
Результат:
[
Hello, World! - <class 'str'>
C:/example/path - <class 'pathlib.PosixPath'>
42 - <class 'int'> {'key': 'value'} - <class 'dict'>
[1, 2, 3] - <class 'list'>
]
Пример 2.2: Несколько списков
pprint(example_list+example_list_2)
Результат:
[
Hello, World! - <class 'str'>
C:/example/path - <class 'pathlib.PosixPath'>
42 - <class 'int'> {'key': 'value'} - <class 'dict'>
Python is fun! - <class 'str'>
/home/user/project - <class 'pathlib.PosixPath'>
99 - <class 'int'>
{'name': 'Alice', 'age': 30, 'languages': ['Python', 'JavaScript', 'C++']} - <class 'dict'>
]
Пример 3: Словарь
from pathlib import Path
import json
example_dict = {
"name": "Alice",
"age": 30,
"address": {
"street": "123 Main St",
"city": "Wonderland"
},
"files": [Path("C:/file1.txt"), Path("C:/file2.txt")]
}
pprint(example_dict)
Результат:
{
{
"name": "Alice",
"age": 30,
"address":{
"street": "123 Main St",
"city": "Wonderland"
},
"files": [ "C:/file1.txt", "C:/file2.txt" ]
}
Пример 4.1: Объект класса MyClass
class MyClass:
def __init__(self, name, value):
self.name = name
self.value = value
def display(self):
return f"{self.name} has value {self.value}"
# Create an instance of the class
obj = MyClass(name="TestObject", value=100)
# Print object information
pprint(obj)
Результат:
<__main__.MyClass object at 0x797a27f17b50>
Class: MyClass
['object']
'Methods:'
'display()'
Properties:
'name = TestObject'
'value = 100'
Пример 4.2: Объект класса Path
import os
from pathlib import Path
current_path = Path(os.getcwd()).resolve()
pprint(current_path)
Результат:
/content
Class: PosixPath
['Path', 'PurePosixPath']
'Methods:'
...
'absolute()'
'as_posix()'
'as_uri()'
'chmod()'
'cwd()'
'exists()'
'expanduser()'
'glob()'
'group()'
'hardlink_to()'
'home()'
...
Properties:
...
'anchor = /'
'drive = '
'name = content'
'parent = /'
'parents = <PosixPath.parents>'
"parts = ('/', 'content')"
'root = /'
'stem = content'
'suffix = '
'suffixes = []'
Пример 5: печать содержимого файла JSON
import json
from pathlib import Path
dct = {
"имя": "Руслан",
"возраст": 25,
"город": "Москва",
"навыки": ["Python", "Наука о данных"]
}
# Save the dictionary to a JSON file
with open(Path('example_json.json'), 'w', encoding='utf-8') as f:
json.dump(dct, f, ensure_ascii=False, indent=4)
# Pretty print the JSON file
pprint('example_json.json')
Результат:
{
"имя": "Руслан",
"возраст": 25,
"город": "Москва",
"навыки": [ "Python", "Наука о данных" ]
}
Пример 6: печать первых 10 строк из файла ТХТ
from pathlib import Path
s = """1: В лесу родилась ёлочка,
2: В лесу она росла.
3: Зимой и летом стройная,
4: Зелёная была.
5: Метель ей пела песенку:
6: «Спи, ёлочка, бай-бай!»
7: Мороз снежком укутывал:
8: «Смотри, не замерзай!»
9: Трусишка зайка серенький
10: Под ёлочкой скакал.
11: Порою волк, сердитый волк,
12: Рысцою пробегал.
13: Чу! Снег по лесу частому
14: Под полозом скрипит.
15: Лошадка мохноногая
16: Торопится, бежит."""
# Save text file
with open(Path('example_txt.txt'), 'w', encoding='utf-8') as f:
f.write(s)
max_lines=10 # <- количество выводимых на печать строк
# Call pprint with the correct filename
pprint('example_txt.txt', max_lines=max_lines)
Результат:
1: В лесу родилась ёлочка,
2: В лесу она росла.
3: Зимой и летом стройная,
4: Зелёная была.
5: Метель ей пела песенку:
6: «Спи, ёлочка, бай-бай!»
7: Мороз снежком укутывал:
8: «Смотри, не замерзай!»
Пример 7: печать первых двух строк из файла CSV
import csv
from pathlib import Path
# Содержимое example.csv:
csv_data = """имя,возраст,город
Алексей,30,Москва
Борис,25,Санкт-Петербург
Виктор,35,Казань
Дмитрий,28,Новосибирск
Екатерина,22,Екатеринбург
"""
# Создание CSV файла
with open(Path('example.csv'), 'w', encoding='utf-8') as f:
f.write(csv_data)
pprint('example.csv', max_lines=2)
Результат:
CSV Header: ['имя', 'возраст', 'город']
Row 1: ['Алексей', '30', 'Москва']
Row 2: ['Борис', '25', 'Санкт-Петербург']
Пример 8: печать первых трёх строк из файла XLS
import pandas as pd
from pathlib import Path
# Create a sample DataFrame and save it as an Excel file
data = {
"имя": "Руслан",
"возраст": 25,
"город": "Москва",
"навыки": ["Python", "Наука о данных"]
}
df = pd.DataFrame(data)
# Save the DataFrame as an .xlsx file
df.to_excel('example.xlsx', index=False)
# Print the file name using pprint
pprint('example.xlsx', max_lines=3)
Результат:
имя возраст город навыки
Руслан 25 Москва Python
Руслан 25 Москва Наука о данных
Для запуска и проверки кода я сделал Интерактивный блокнот google colab. здесь все наглядно с примерами
Программирование на python
884 поста11.9K подписчиков
Правила сообщества
Публиковать могут пользователи с любым рейтингом. Однако!
Приветствуется:
• уважение к читателям и авторам
• конструктивность комментариев
• простота и информативность повествования
• тег python2 или python3, если актуально
• код публиковать в виде цитаты, либо ссылкой на специализированный сайт
Не рекомендуется:
• допускать оскорбления и провокации
• распространять вредоносное ПО
• просить решить вашу полноценную задачу за вас
• нарушать правила Пикабу