Python / Атрибуты между методами класса

#python-3.x

#python-3.x

Вопрос:

Я новичок в Python и пытаюсь разобраться, как управляются атрибуты между методами класса.

В следующем примере я пытаюсь изменить список в методе «regex» и впоследствии использовать его в другом методе «printsc».

Часть «regex» работает без проблем, но атрибут «self.mylist» не обновляется, поэтому, когда я вызываю «printsc», результатом является «None».

 class MyClass():
    def __init__(self):
        self.mylist = None

    def regex(self, items):
        self.mylist = []
        for item in items:
            if re.match(r"^d{1,3}.d{1,3}.d{1,3}.d{1,3}$", item):
                self.mylist.append("IP:"   item)
            else:
                self.mylist.append("DNS:"   item)
        return self.mylist

    def printsc(self):
        print(self.mylist)

items = ['192.168.0.1', 'hostname1', '10.0.1.15', 'server.local.fr']

MyClass().regex(items)
MyClass().printsc()
  

Чего мне не хватает? Каков наилучший способ достижения этой цели?

Спасибо за ваши ответы!

Ответ №1:

Когда вы выполняете функцию MyClass(), она возвращает вам объект.. И вы вызываете свои методы для объекта. Поскольку вы делаете это дважды, каждый раз создается новый объект, а regex и printsc вызываются для разных объектов.

что вам следует сделать, так это

 myObj = MyClass()
myObj.regex(items)
myObj.printsc()
  

Комментарии:

1. Так просто… Спасибо! 😉

Ответ №2:

Проблема в том, что когда вы делаете:

 MyClass().regex(items)
MyClass().printsc()
  

Вы создаете 2 отдельных экземпляра MyClass, каждый из которых будет иметь свой .mylist атрибут.

Либо mylist является атрибутом экземпляра, и тогда это будет работать:

 instance = MyClass()
instance.regex(items)
instance.printsc()
  

Или, если вы хотите разделить .mylist между экземплярами, это должно быть
атрибут класса:

 class MyClass():
    class_list = None
    def __init__(self):
        pass
        

    def regex(self, items):
        cls = self.__class__
        if cls.class_list is None:
            cls.class_list = []
        for item in items:
            if re.match(r"^d{1,3}.d{1,3}.d{1,3}.d{1,3}$", item):
                cls.class_list.append("IP:"   item)
            else:
                cls.class_list.append("DNS:"   item)
        return cls.class_list

    def printsc(self):
        # Going throuhgh `.__class__.` is actually optional for 
        # reading an attribute - if it is not in the instance
        # Python will fetch it from the class instead.
        # i.e. ,  the line bellow would work with `self.class_list`
        print(self.__class__.class_list)
  

Таким образом, список сохраняется в разных экземплярах класса, как вы пытаетесь сделать в вашем примере.

Комментарии:

1. Спасибо @jsbueno, также было бы полезно поделиться списком между экземплярами

Ответ №3:

Вы должны создать объект класса:

 a = MyClass()
a.regex(items)
a.printsc()

>>> ['IP:192.168.0.1', 'DNS:hostname1', 'IP:10.0.1.15', 'DNS:server.local.fr']