86050


今、python3をterminalから

[code]

    python3 sample.py path/to/file 
    
[/code]

で動かそうとしています。  
そのsample.pyの中身が：

[code]

    import os
    import sys
    import re
    
    class Solution:
        def parse_filename(fn):
            m = re.match(r'(\D*)(\d*)\.(.*)$', fn)
            return (m[0], m[1], int(m[2]), m[3])
    
        args = sys.argv 
        if len(args) < 2:
            files = os.listdir(os.getcwd()) # if no argument is provided, use the CWD
        else: 
            files = os.listdir(args[1]) # path/to/file
    
        print("inside the files: ", files)
        parsed_files = [parse_filename(fn) for fn in files]　# ココに問題あり。
        print("inside the parsed_files: ", parsed_files)
    
[/code]

上のコードでやろうとしているのは、os.listdir("path/to/file")で取ってきたファイルはファイル名が「名前＋数字＋拡張子」の形で保存されており（例：foobar12.png,
hogehoge3.jpg）ソートする際に名前のアルファベット順ではなく、数字でソートせねばなりません。つまり上の例であればhogehoge3.jpgがfoobar12.pngより先に来ます。しかし上記のコードをterminalで実行すると以下のようなNameErrorになってしまい原因が分かりません。初心者質問で申し訳ないですが、どなたか解決策をご存知ですか？

[code]

    Traceback (most recent call last):
      File "/Users/.../sample.py", line 8, in <module>
        class Solution:
      File "/Users/.../sample.py", line 41, in Solution
        parsed_files = [parse_filename(fn) for fn in files]
      File "/Users/.../sample.py", line 41, in <listcomp>
        parsed_files = [parse_filename(fn) for fn in files]
    NameError: name 'parse_filename' is not defined
    
[/code]


CC BY-SA 4.0
2022-01-31T16:54:32.887
86048
2022-01-31T23:48:40.887
2022-01-31T23:48:40.887
3060
35503
question
python
pythonのNameErrorの原因が分かりません。


原因は該当の処理がクラス定義の中に組み込まれた形になっているためです。  
以下のいずれかの方法で修正出来るでしょう。

* * *

この程度の処理であれば`class Solution:`を定義する必要は無いので外してインデントを1段浅くする。

[code]

    import os
    import sys
    import re
    
    def parse_filename(fn):
        m = re.match(r'(\D*)(\d*)\.(.*)$', fn)
        return (m[0], m[1], int(m[2]), m[3])
    
    args = sys.argv 
    if len(args) < 2:
        files = os.listdir(os.getcwd()) # if no argument is provided, use the CWD
    else: 
        files = os.listdir(args[1]) # path/to/file
    
    print("inside the files: ", files)
    parsed_files = [parse_filename(fn) for fn in files]
    print("inside the parsed_files: ", parsed_files)
    
[/code]

* * *

質問のソースコード内容をなるべく変えないで修正する場合、  
`if __name__ ==
'__main__':`が不足しているのと、メソッド呼び出しに(Solutionオブジェクトを作らない場合)クラス名指定が不足している。

[code]

    import os
    import sys
    import re
    
    class Solution:
        def parse_filename(fn):
            m = re.match(r'(\D*)(\d*)\.(.*)$', fn)
            return (m[0], m[1], int(m[2]), m[3])
    
    if __name__ == '__main__': #### この行が不足している
        args = sys.argv 
        if len(args) < 2:
            files = os.listdir(os.getcwd()) # if no argument is provided, use the CWD
        else: 
            files = os.listdir(args[1]) # path/to/file
    
        print("inside the files: ", files)
        parsed_files = [Solution.parse_filename(fn) for fn in files] #### 呼び出し方をクラス名.メソッド名とする
        print("inside the parsed_files: ", parsed_files)
    
[/code]

* * *

Solutionオブジェクトを作って呼び出す場合は以下のようにする。

[code]

    import os
    import sys
    import re
    
    class Solution:
        def parse_filename(self, fn): #### selfパラメータが不足している
            m = re.match(r'(\D*)(\d*)\.(.*)$', fn)
            return (m[0], m[1], int(m[2]), m[3])
    
    if __name__ == '__main__': #### この行が不足している
        args = sys.argv 
        if len(args) < 2:
            files = os.listdir(os.getcwd()) # if no argument is provided, use the CWD
        else: 
            files = os.listdir(args[1]) # path/to/file
    
        print("inside the files: ", files)
        sln = Solution()                                        #### Solutionオブジェクトを作成しておく
        parsed_files = [sln.parse_filename(fn) for fn in files] #### 呼び出し方をオブジェクト名.メソッド名とする
        print("inside the parsed_files: ", parsed_files)
    
[/code]


CC BY-SA 4.0
2022-01-31T23:03:51.050
86050
2022-01-31T23:03:51.050
26370
86048
answer