@lemonlimelike

Как правильно реализовать ООП python?

Всем привет! Начал изучать пайтон, легко дался. Решил первым делом написать бота для телеге. Скрипта не жалко в принципе. Хочу так сказать поинтересоваться и попросить опытных питоноводов указать на ошибки при использование ООП. Имеется ввиду, правильно ли я реализую вызов метода в методе и тому подобное.
import telebot
import requests
import pprint
import time

botToken = "token"
chanelName = "@wo"

class Bot:
	def __init__(self,nameChanel,token):
		self.name = nameChanel
		self.bot = telebot.TeleBot(token)
		#self.source = source

	def getIDGroup(self,str):
		arr = []
		for nameGroup in str:
			url = f"url"
			response = requests.get(url).json()['response']['object_id']
			arr.extend(self._getPostsGroup(response))
		return self._editPosts(arr)

	def _getPostsGroup(self,number):
		number = str(number)
		url = f"url"
		response = requests.get(url).json()['response']['items']
		return response

	def _editPosts(self,posts):
		with open('id.txt','r') as file:
			list = file.read().split()
			file.close()
		
		for item in posts:
			count = list.count(str(item['id']))
			if count:
				continue
			photo = ""
			for img in item['attachments'][0]['photo']['sizes']:
				if img['height'] > 300:
					photo = img['url']
					break
			text = item['text']

			self._sendMessageBot(text,photo)
			with open('id.txt','a') as file:
				file.write(str(item['id'])+' ')
				file.close()

	def _sendMessageBot(self,text,photo):
		if photo:
			if text:
				self.bot.send_photo(self.name,photo,caption=text)
				return
			else:
				self.bot.send_photo(self.name,photo)
		if text:
			self.bot.send_message(self.name,text)

bot = Bot(chanelName, botToken)
posts = bot.getIDGroup() #name of group
  • Вопрос задан
  • 2299 просмотров
Решения вопроса 1
trapwalker
@trapwalker Куратор тега Python
Программист, энтузиаст
import telebot
import requests
import pprint
import time

botToken = "token"
chanelName = "@wo"

class Bot:
  def __init__(self,nameChanel,token):
    # todo: проверьте pep8: форматирование (пробелы, indent=4), нейминг (CamelCase vs snake_case)
    self.name = nameChanel
    self.bot = telebot.TeleBot(token)
    # todo: Неадекватное имя bot. Вызывает путаницу в связи с именем класса Bot
    #self.source = source

  def getIDGroup(self,str):
    # todo: str - это встроенный тип, по смыслу должно быть ясно, что можно итерировать
    arr = []
    # todo: Неадекватное имя arr. Имя должно указывать не на тип, а на суть того, что поименовано.
    for nameGroup in str:
      url = f"url"  # todo: Зачем тут форматная строка, если нет переменных? Видимо ошибка.
      response = requests.get(url).json()['response']['object_id']
      # todo: Где проверка ответа на ошибки?
      # todo: Неадекватное имя. Назовите object_id
      arr.extend(self._getPostsGroup(response))
    return self._editPosts(arr)

  def _getPostsGroup(self,number):
    # todo: Неадекватное имя number. Назовите group_id 
    number = str(number)
    url = f"url"
    response = requests.get(url).json()['response']['items']
    # todo: Неадекватное имя. Назовите object_id
    return response

  def _editPosts(self,posts):
    with open('id.txt','r') as file:
      list = file.read().split()
      # todo: имя переменной перекрывает встроенный тип, не отражает содержимое
      # todo: Зачем read и split, если можно list(file) и идентификаторы хранить в строках?
      file.close()
      # todo: Зачем close, если with?!
    
    for item in posts:
      count = list.count(str(item['id']))
      # todo: Зачем вам тут count, если нужна лишь проверка на вхождение?
      if count:
        continue
      photo = ""
      # todo: почему не None?
      for img in item['attachments'][0]['photo']['sizes']:
        if img['height'] > 300:
          photo = img['url']
          break
      text = item['text']

      self._sendMessageBot(text,photo)
      with open('id.txt','a') as file:
        # todo: ну использовали бы уже хотя бы shelve
        file.write(str(item['id'])+' ')
        file.close()
        # todo: опять close


  def _sendMessageBot(self,text,photo):
    if photo:
      if text:
        self.bot.send_photo(self.name,photo,caption=text)
        return
      else:
        self.bot.send_photo(self.name,photo)
    if text:
      self.bot.send_message(self.name,text)

    # Функция могла выглядеть так:
    # if photo:
    #   self.bot.send_photo(self.name, photo, caption=text)
    # elif text:
    #   self.bot.send_message(self.name, text)
    # Но лучше не допускать вызова с пустыми аргументами. Это бессмысленно и плохо

bot = Bot(chanelName, botToken)
# вот как понимать такое: bot.bot? Нейминг!!!
posts = bot.getIDGroup() #name of group

Зачем каждый раз читать и писать файл, когда у вас бот в памяти остаётся?
По меньшей мере вы можете хотя бы не читать каждый раз, сохраняя идентификаторы в множестве памяти (кэш), а загружать это множество из файла только при старте бота. Писать можно и так. Но у вас функции не соответствуют принципу single responsibility (почитайте SOLID)

Всё плохо. Прежде чем думать об ООП почитайте хотя бы туториал по питону или любую книжку Питон для чайников.
Хороший тон давать код на ревью в гитхабе. Там можно удобно, с подсветкой синтаксиса и нумерацией строк прокомментировать весь ваш ... код, а вы сможете его потом итеративно улучшать и мне не придётся заново убеждаться, что вы учли все замеченные проблемы при повторном ревью.
Вот бесит прям. Пожалуй не буду больше ревьюить первые потуги настолько самоуверенных программистов. Просто не вежливо дёргать сообщество не почитав даже основы.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
tumbler
@tumbler Куратор тега Python
бекенд-разработчик на python
Тут нет ООП. Набор функций (привет, процедурное программирование) зачем-то сгруппирован в класс, у которого инстанцируется единственный экземпляр.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы