Превращение функций в ООП

У меня есть такой json-словарь:

{
  "name": "Root Folder",
  "type": "folder",
  "children": [
    {
      "name": "Folder A",
      "type": "folder",
      "children": [
        {
          "name": "Folder A-A",
          "type": "folder",
          "children": [
            {
              "name": "File A-A-1",
              "type": "file",
              "children": []
            }
          ]
        },
        {
          "name": "Folder A-B",
          "type": "folder",
          "children": []
        }
      ]
    },
    {
      "name": "Folder B",
      "type": "folder",
      "children": [
        {
          "name": "Folder B-A",
          "type": "folder",
          "children": [
            {
              "name": "Folder B-A-A",
              "type": "folder",
              "children": []
            }
          ]
        },
        {
          "name": "Folder B-B",
          "type": "folder",
          "children": []
        }
     ]
   },
   {
      "name": "File Root",
      "type": "file",
      "children": []
   }
  ]
}

из этого словаря я хочу автоматически получать значения «Путь», «Имя» и «тип» для каждого члена, а также для уровня, так что корень - level0, папка A - уровень 1, папка AA - уровень 2 и так далее.

Для этой цели я создал следующий код Python, который берет json-словарь и помещает значения из него в массивы:

import json
import os
from jinja2 import Template


with open('Folder_structure.json') as f:
    data = json.load(f)

def arr4tmpl(data,arr_path,arr_name,arr_type,arr_level):

    for child in data['children']:

        arr_path.extend([child['path']])
        arr_name.extend([child['name']])
        arr_type.extend([child['type']])
        arr_level.extend([arr4tmpl.level])

        arr4tmpl.level+=1
        arr4tmpl(child,arr_path,arr_name,arr_type,arr_level)
        arr4tmpl.level-=1

    return(arr_path,arr_name,arr_type,arr_level)

def main():
    arr4tmpl.level = 0
    arr=[]
    arr_path=[]
    arr_name=[]
    arr_type=[]
    arr_level=[]

(arr_path,arr_name,arr_type,arr_level)=arr4tmpl(data,arr_path,arr_name,arr_type,arr_level)

Это прекрасно работает, но теперь его нужно превратить в объектно-ориентированное решение. Итак, я подумал о следующем (отредактировано по ответам, на этом спасибо):

import json
import os
from jinja2 import Template

class CreateTemplate(object):

    def __init__(self):
        self.arr_path=[]
        self.arr_name=[]
        self.arr_type=[]
        self.arr_level=[]
        self.level=0


    def arr4tmpl(self,data,level):
        for child in data['children']:

            arr_path.extend([child['path']])
            arr_name.extend([child['name']])
            arr_type.extend([child['type']])
            arr_level.extend([level])

            level+=1
            arr4tmpl(self,child,level)
            level-=1


        return(arr_path,arr_name,arr_type,arr_level)


with open('Folder_structure.json') as f:
    data = json.load(f)
template=CreateTemplate()
template.arr4tmpl(data,level)

Идея состоит в том, чтобы инициализировать параметры с помощью метода в этом, а затем расширить их с помощью метода arr4tmpl. Насколько я понимаю, создание объекта должно запускать метод init, но при выполнении кода я получаю ошибку:

File "Folder_structure.py", line 34, in <module>
template.arr4tmpl(data,level)
NameError: name 'level' is not defined

вы не звоните членам класса

Mohammad Athar 12.06.2018 18:21

Не забывайте, что вам все равно нужно ссылаться на self внутри вашего метода arr4tmpl - поэтому arr_path.extend(...), скорее всего, должен быть self.arr_path.extend(...) и т. д.

jedwards 12.06.2018 18:22

Добро пожаловать в StackOverflow. Пожалуйста, прочтите и следуйте инструкциям по публикации в справочной документации, как было предложено при создании этой учетной записи. Здесь применяется Минимальный, полный, проверяемый пример. Мы не сможем эффективно помочь вам, пока вы не опубликуете свой код MCVE и точно не опишете проблему. Мы сможем вставить ваш опубликованный код в текстовый файл и воспроизвести описанную вами проблему. «Не работает» - это не спецификация проблемы.

Prune 12.06.2018 18:22
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
3
53
2

Ответы 2

Если вы хотите изменить переменные объекта, вы должны ссылаться на них, используя self.

def arr4tmpl(self,data,level):
    for child in data['children']:    

        self.arr_path.extend([child['path']])
        self.arr_name.extend([child['name']]) 
        self.arr_type.extend([child['type']])
        self.arr_level.extend([level])

        self.level+=1
        self.arr4tmpl(self,child,level) #BUT this line will cause all sorts of recursion issues, since you don't have a stop criteria
        self.level-=1


    return(arr_path,arr_name,arr_type,arr_level)

ах да, я действительно нашел способ:

import json
import os
from jinja2 import Template

class CreateTemplate(object):

    arr_path=[]
    arr_name=[]
    arr_type=[]
    arr_level=[]
    level=0



    def arr4tmpl(self,data):
        for child in data['children']:

            self.arr_path.extend([child['path']])
            self.arr_name.extend([child['name']])
            self.arr_type.extend([child['type']])
            self.arr_level.extend([self.level])

            self.level+=1
            self.arr4tmpl(child)
            self.level-=1


        return(self.arr_path,self.arr_name,self.arr_type,self.arr_level)


with open('Folder_structure.json') as f:
    data = json.load(f)
template=CreateTemplate()

template.arr4tmpl(data)

Не уверен, почему init также не работает, потому что я полагал, что он инициализирует параметры при создании объекта, а затем эти переменные могут использоваться для метода arr4tmpl.

Также не уверен, можно ли улучшить метод arr4tmpl, но, по крайней мере, он сейчас создает эти массивы. Спасибо!

Другие вопросы по теме