Why variable is available in function without declaring ? - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: Web Scraping & Web Development (https://python-forum.io/forum-13.html) +--- Thread: Why variable is available in function without declaring ? (/thread-9974.html) |
Why variable is available in function without declaring ? - winmasta - May-07-2018 #!/usr/bin/python3 # -*- coding: utf-8 -*- import requests from bs4 import BeautifulSoup import re from datetime import datetime from datetime import timedelta import logging from logging.handlers import RotatingFileHandler from os import path from time import sleep def get_settings(file): settings = {} try: with open(file) as f: for line in f: try: arr = line.split(":") arr = [line.strip() for line in arr] settings[arr[0]] = arr[1] except IndexError: continue except FileNotFoundError as e: print(e) exit(1) return settings def find_string(expr): pattern = re.compile(r"{}".format(expr)) string = soup.find(text=pattern).__dict__ return string def get_date(string): match = re.findall(r"\d{4}-\d{2}-\d{2}", string) return match def get_ok(string): pattern = re.compile("glyphicon-ok") match = re.search(pattern, str(string)) if not match: return False else: return True def unsent_checks(): string = find_string("Неотправленные чеки")["next_element"].getText() res = get_date(string) try: date = datetime.strptime(res[0], '%Y-%m-%d').date() except (AttributeError, IndexError): date = None if date: return string else: return None def ok_check(string): string = find_string(string) res = get_ok(string["previous_element"]) if not res: logger.error(string["next_element"].getText()) def check_date(string, days): string = find_string(string)["next_element"].getText() date = get_date(string)[1] date = datetime.strptime(date, '%Y-%m-%d').date() - timedelta(days) if datetime.now().date() > date: logger.warning(string) settings_vars = get_settings("{}/settings.yaml".format(path.dirname(path.abspath(__file__)))) log_format = "%(asctime)s - %(levelname)s: %(message)s" logger = logging.getLogger("log") logger.setLevel("INFO") handler = RotatingFileHandler("{}/{}".format(path.dirname(path.abspath(__file__)), settings_vars["log_filename"]), maxBytes=1024, backupCount=5) logger.addHandler(handler) formatter = logging.Formatter("%(asctime)s - %(levelname)s: %(message)s") handler.setFormatter(formatter) logging.getLogger("urllib3").setLevel(logging.WARNING) try: cert_warn_days = int(settings_vars["cert_warn_days"]) except ValueError: cert_warn_days = None logger.error("check 'cert_warn_days' in settings.yaml") exit(1) text = requests.get("http://{}:{}".format(settings_vars["utm_address"], settings_vars["utm_port"])).text soup = BeautifulSoup(text, 'html.parser') unsent_error_counter = 0 while True: unsent_string = unsent_checks() if unsent_string: unsent_error_counter += 1 if unsent_error_counter > settings_vars["unsent_error_limit"]: logger.error(unsent_string) unsent_error_counter = 0 ok_check("Продуктивный контур") ok_check("Статус лицензии") check_date("Сертификат RSA", cert_warn_days) check_date("Сертификат ГОСТ", cert_warn_days) logger.info("OK") sleep(60)It was written by me but now I really can't understand why "soup" is available in "def find_string(expr)" Can anybody explain ? By the way may be there is some weakness in my code ? Now I understand ))) RE: Why variable is available in function without declaring ? - wavic - May-07-2018 soup is BeautifulSoop() instance. It is available in the global space. Python first looks in function's local namespace for the objects and if they are not there it looks in the global namespace. As time module in your script: import time def the_time(): print(time.asctime()) the_time()So you create BeautifulSoup object called soup. Which has a bunch of methods. It is not indented so it is in the global namespace and you can access it directly. Just like time. In [1]: from bs4 import BeautifulSoup In [2]: import requests In [3]: html = requests.get('http://python-forum.io/').content In [4]: BeautifulSoup(html, 'lxml').find('title').text Out[4]: 'Python Forum'Here I am not creating any BS object. I can use this or the eventually created 'soup' object in any function definition. In [5]: soup = BeautifulSoup(html, 'lxml') In [6]: for obj in dir(): ...: if obj == 'soup': ...: print(obj) ...: soup In [7]: def get_title(): ...: title = BeautifulSoup(html, 'lxml').find('title').text ...: print(title) ...: title = soup.find('title').text ...: print('soup object', title) ...: In [8]: get_title() Python Forum soup object Python ForumYou can also pass it as an argument for sure. In [9]: def get_title(inner_soup): ...: title = BeautifulSoup(html, 'lxml').find('title').text ...: print(title) ...: title = inner_soup.find('title').text ...: print('inner_soup object', title) ...: In [10]: get_title(soup) Python Forum inner_soup object Python Forum RE: Why variable is available in function without declaring ? - winmasta - May-07-2018 Thanks. Spasibo))) RE: Why variable is available in function without declaring ? - wavic - May-07-2018 Dla nichevo |