Можете ли вы генерировать новые имена внутри класса? - PullRequest
0 голосов
/ 18 января 2019

Попытка выяснить, как использовать функцию для генерации новых именованных переменных внутри класса.

Я поиграл с этим в IDLE и искал онлайн-документы. Решение намекает на меня.

>>> import random

>>> abc = [(map(chr,range(ord('A'),ord('Z')+1)))+(map(chr,range(ord('a'),ord('z')+1)))]

>>> class Test():
        def __init__(self, abc):
            self.a = 0
            self.abc = abc

        def newSelf(self):
            for i in range(2):
                b = random.choice(abc)
                c = random.choice(abc)
                globals()['self.'+b+c] = 0
                #or
                locals()['self.'+b+c] = 0
                print(b+c,0)

>>> example = Test(abc)
>>> example.a
0
>>> example.newSelf() #say it generates
An 0
ze 0
>>> example.An #calling new self variable of example object returns

Traceback (most recent call last):
  File "<pyshell#221>", line 1, in <module>
    example.An
AttributeError: 'Test' object has no attribute 'An'

# I'm hoping for...
>>> example.An
0

1 Ответ

0 голосов
/ 18 января 2019

Использование setattr:

Вы можете использовать setattr для установки нового атрибута:

>>> class Test():
...     def __init__(self, abc):
...         self.a = 0
...         self.abc = abc
...     def newSelf(self):
...         for i in range(2):
...             b = random.choice(abc)
...             c = random.choice(abc)
...             setattr(self, b+c, 0)
...             print(b+c,0)

И атрибут снова будет доступен:

>>> example = Test(abc)
>>> example.newSelf()
zM 0
Ja 0
>>> example.zM
0
>>> example.Ja
0

Использование exec:

Вы можете использовать функцию exec для выполнения инструкции python, хранящейся в строке. Так как вы генерируете имя переменной случайным образом, вы можете создать весь оператор python в строке и выполнить этот оператор, используя exec, как показано ниже:

>>> class Test():
...     def __init__(self, abc):
...         self.a = 0
...         self.abc = abc
...     def newSelf(self):
...         for i in range(2):
...             b = random.choice(abc)
...             c = random.choice(abc)
...             exec('self.'+b+c+' = 0')
...             print(b+c,0)

Здесь я создал новый атрибут, используя exec('self.'+b+c+' = 0'). Теперь после вызова этого метода будет доступен атрибут:

>>> example = Test(abc)
>>> example.newSelf()
Tw 0
Xt 0
>>> example.Tw
0
>>> example.Xt
0
...