Python 基本メモ import_moduleでクラスを動的import

Pythonで書いた1回限りの処理用の使い捨てスクリプトをスケジュールで定期的に処理する必要があって、調べてましたが、まだ初心者で、ダブルアンダースコアの変数の使い方がよくわからず、
意図した動作が出来ないので、使うスクリプトをクラスにしましたところ、うまく動きめでたく解決しました。
昔、Javaのリフレクションを使って同様のことをしてましたが、長いコードが必要だったのが、短く済みすっきりと出来ました。

< コード例 >

コマンドライン引数で指定した自作モジュールのインポート



import importlib

# クラス名引数 #
args = sys.argv
module_name = ""
if len(args) != 2:
    print("No argument unable to continue!!")
    sys.exit()
    #module_name = "MatsumotoClass" 
else:
    module_name = args[1] + "Class"

sttm = int(time.time())

## 動的モジュール読込 ##
mod = importlib.import_module(module_name)
## インスタンス化 ##
md = mod.ExecClass()

Python 基本メモ 関数内関数

Javascriptと同じく関数内関数が使えるので使ってみました。
別の関数にするまでもない短いのや、勘違いして必要なデータ取得が欠けた時とかに使ってます。

< コード例 >


    # 店舗ページから住所取得 #
    def getAddr (url) -> str: 
      soup = sp.Soup.getSoupText(URL_TOP + url)
      return soup.find_all("td")[0].text[10:]
    
    namelist = [p.text for p in soup.find_all("p", class_="title") 
                if p.text.endswith("店")]
    # 住所が別ページだったので関数内関数で取得 #
    addrlist = [getAddr(p.find("a")["href"]) for p in soup.find_all("p", class_="title") if p.text.endswith("店")]

Python 基本メモ Googleジオコーダー

クラスにしてみました。


import googlemaps

class Google:
    
    API_KEY = "???????????????????????????????????????"
  
    '''
    コンストラクタ
    '''

    def __init__(self, address):
        self.address = address
    
    # ジオコーダー実行 経緯度、郵便番号返却 #
    def getLatLonZip(self) -> dict:
        
        dict = {"lat": -500, "lon": -500, "zip": "000-0000"}
        
        gmaps = googlemaps.Client(key=Google.API_KEY)
        result = gmaps.geocode(self.address)
        #print(result[0])
        
        if len(result) > 0:
            lat = result[0]["geometry"]["location"]["lat"]
            lon = result[0]["geometry"]["location"]["lng"]
        
            dict["zip"] = ""
            addrcomps = result[0]["address_components"]
            for adc in addrcomps:
                if adc["types"][0] == "postal_code":
                     dict["zip"] = adc["long_name"]
                 
            print (lat,lon, zip)
        
            dict["lat"] = lat
            dict["lon"] = lon
        
        return dict

import


import geoclass.Google as g

呼び出し


 # 経緯度、郵便番号ジオコーダー #
 geo = g.Google(addr)
 llz = geo.getLatLonZip()

Python 基本メモ データクラス

< コード例 >

クラス


'''
住所録データクラス
'''
from dataclasses import dataclass, field

@dataclass
class Address():
  gp: str        # グループ名
  list: str      # リスト名
  name: str      # 施設店舗名
  addr: str      # 住所
  tel: str       # 電話番号
  lat: float     # 緯度
  lon: float     # 経度
  zip: str       # 郵便番号
  icon: str      # マーカーアイコンファイル名

  ## 辞書型を使った場合 ##
  # dict = {"gp": GP, "list": LIST_NAME, "name": name, "addr": addr, "tel": tel,
  #                  "lat": llz["lat"], "lon": llz["lon"], "zip": llz["zip"], "icon": ICON_NAME}

import


import dclass.AddressData as ad

値の格納


# データクラス #
add: ad.Address = ad.Address(gp=GP, list=LIST_NAME, name=nm, addr=addr, tel="",
            lat=llz["lat"], lon=llz["lon"], zip=llz["zip"], icon=ICON_NAME)
print(add)
dictlist_dc.append(add)

Python 基本メモ ループでzipを使う

最近になって、Pythonを始めてみました。
Javaで行っていたWEBページのスクレープをPythonに移行中です。
今更ながらと言われるかも知れませんが、Javaに比べてコードが大きく減らせて、大幅生産性向上が出来て驚いてます。
そんな中で、リスト内包表記と同じく便利なので使ってるzip関数による複数変数ループを備忘録しておきます。

< コード例 >


## ++ 店名 住所 電話番号 走査 ++ ##  
for nm, addr, tel in zip(namelist, addrlist, tellist):
  
  # 経緯度、郵便番号ジオコーダー #
  if addr is not None and addr != "":
    geo = g.Google(addr)
    llz = geo.getLatLonZip()
    
    dict = {"gp": GP,"list": LIST_NAME, "name": nm, "addr": addr, "tel": tel, 
    "lat": llz["lat"], "lon": llz["lon"], "zip": llz["zip"], "icon": ICON_NAME}
    print(dict)
    dictlist.append(dict)
  
return dictlist

Python 時刻形式経緯度十進変換関数クラス

航空や気象で扱われてる時刻形式の経緯度を地図で扱うために、十進値に変換する関数を作ってクラスにしてみました。

< コード例 >

クラス


'''
時刻形式経緯度十進変換クラス
'''
class DigitLL:

  '''
  コンストラクタ
  txt : 時刻経緯度
  endchr : N or S or E or W
  '''
  def __init__(self, txt, endchr):
    self.txt = txt
    self.endchr = endchr

  '''
  十進変換
  '''
  def digitLLFromTimeLL(self):

      numInt = int(self.txt)
      # 整数部
      hourPartVal = int(numInt / 10000)
      # 分
      minutePartVal = int(numInt / 100) % 100
      # 秒
      secondPartVal = numInt % 100

      minuteVal = minutePartVal / 60
      secondVal = secondPartVal / 3600
      resval = hourPartVal + minuteVal + secondVa
      
      # 南半球、西半球の場合 #
      if (self.endchr == "S" or self.endchr == "W
          resval = resval * -1

      # debug
      # print(str(hourPartVal) + ":" + str(minute

      return resval

呼び出し
ダウンロードしたExcelのファイルのセルの値を読み込んで変換する場面で使ってます。


'''
Waypointエクセルファイル読込
使用
wp_euro_procedure.pyから使う

filename : エクセルファイル名
effdate_end : effective expired date
'''
def readExcel(filename, effdate_end):

    wb = openpyxl.load_workbook(filename)
    sheet = wb["FRA Points"]

    # 書き込み用タプルリスト追加 #

    tpllist = []

    # 行数を調べる #
    rowmax = getDataRowMax(sheet)

    # identcol = "C" + str(i + 2)

    ## ++ 辞書値リスト追加走査 ++ ##
    for i in range(rowmax):

        ident = sheet["C" + str(i + 2)].value
        type = sheet["A" + str(i + 2)].value
        latcval = sheet["D" + str(i + 2)].value
        loncval = sheet["E" + str(i + 2)].value
        name = sheet["F" + str(i + 2)].value
        #if type == None:
        #    type = "FIX"
            
        type = "FIX" if type == None else type     

        latendchr = latcval[0:1]
        lonendchr = loncval[0:1]
        latvalpart  = latcval[1:]
        lonvalpart = loncval[1:]

        #lat = digitLLFromTimeLL(latvalpart, latendchr)
        #lon = digitLLFromTimeLL(lonvalpart, lonendchr)
        
        # クラスを使う #
        dll_lat = dll.DigitLL(latvalpart, latendchr)
        dll_lon = dll.DigitLL(lonvalpart, lonendchr)
        
        lat = dll_lat.digitLLFromTimeLL()
        lon = dll_lon.digitLLFromTimeLL()
        
        
        # debug
        print(ident)
        print(latcval + " => " + str(lat))
        print(loncval + " => " + str(lon))
        print("-------------------------------------------")

        tpl = {"type": "", "ident": "", "name": "", "lat": -500, "lon": -500}

        if lat != 0 and lon != 0:
            tpl["type"] = type
            tpl["ident"] = ident
            tpl["name"] = name
            tpl["lat"] = lat
            tpl["lon"] = lon
            tpllist.append(tpl)

< エクセルファイル例 >

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

航空情報 2023年 6月号 [雑誌]
価格:1,425円(税込、送料無料) (2023/5/21時点)

Python tqdmでプログレス表示

ここで教えて頂きました。

< コード例 >


pos = 0
for icao in tqdm(ICAOS):
  url = BASE_URL.replace("##ICAO##", icao[0])
  driver.get(url)
  time.sleep(5)
  pos += 1
  if pos <= 4:
    continue

< 画面例 >

  
 62%|███████████████████████████████████████████████████████████████████████████████████████████████████████████▋                                                                   | 184/299 [38:59<23:30, 12.26s/it]E55P:64257
{}