Использование простой функции в качестве класса с функциями ООП - PullRequest
0 голосов
/ 14 июня 2019

Видя очень интересный код здесь , я пытаюсь использовать функцию как класс со следующим кодом:

def CF_ptrec(sname='', sage=0, sgender=''):
    name = sname
    age = sage
    gender=sgender

    def getname():          
          return name
    def setname(ssname):        
          global name; name = ssname
    def getgender():        
          return gender
    def setgender(ssgender):    
          global gender; gender = ssgender

    def getage():           
          return age
    def setage(ssage):          
        print("in setage fn; val rcd: ", ssage) # just for testing; 
        global age
        age = ssage

    def printrep():
        print("Name: ", name)
        print("Age: ", age)
        print("Gender: ", gender)
        print("===========================")

    return {        # a dictionary
    "getname":getname, "setname":setname, 
    "getage":getage, "setage":setage, 
    "getgender":getgender, "setgender":setgender, 
    "printrep": printrep }

Я могу создавать объекты и вызывать функцию для печати их деталей:

# CREATE OBJECTS: 
arec = CF_ptrec("Ram", 5, "M")
brec = CF_ptrec("Tom", 15, "M")

# PRINT THEIR RECORDS: 
arec["printrep"]()
brec["printrep"]()

Вывод:

Name:  Ram
Age:  5
Gender:  M
===========================
Name:  Tom
Age:  15
Gender:  M
===========================

Однако, если я пытаюсь изменить значение возраста этих объектов, он не работает:

# CHANGE AGE VALUES: 
arec['setage'](25)
brec['setage'](25)

# PRINT RECORDS: 
arec["printrep"]()
brec["printrep"]()

Вывод:

in setage fn; val rcd:  25
in setage fn; val rcd:  25
Name:  Ram
Age:  5
Gender:  M
===========================
Name:  Tom
Age:  15
Gender:  M
===========================

Где проблема и как ее можно решить?

Ответы [ 2 ]

3 голосов
/ 14 июня 2019

Когда вы пытаетесь установить эти значения, вы обращаетесь к global переменным. Переменные, которые вы действительно хотите изменить, не являются глобальными , но находятся в области действия CF_ptrec. Вам нужно использовать nonlocal age вместо этого. В настоящее время вы устанавливаете глобальную переменную age, но читает age из области действия CF_ptrec.

0 голосов
/ 16 июня 2019

Опираясь на ответ @Deceze, вот ваш пример, измененный с использованием ключевого слова nonlocal: ([edit]: другими словами, это код, который вы получаете при применении ответа @Deceze)

def CF_ptrec(sname='', sage=0, sgender=''):
    name = sname
    age = sage
    gender=sgender

    def getname():          
        return name

    def setname(ssname):        
        nonlocal name
        name = ssname

    def getgender():        
        return gender

    def setgender(ssgender):    
        nonlocal gender
        gender = ssgender

    def getage():           
        return age

    def setage(ssage):          
        print("in setage fn; val rcd: ", ssage) # just for testing; 
        nonlocal age
        age = ssage

    def printrep():
        print("Name: ", name)
        print("Age: ", age)
        print("Gender: ", gender)
        print("===========================")

    return {        # a dictionary
    "getname":getname, "setname":setname, 
    "getage":getage, "setage":setage, 
    "getgender":getgender, "setgender":setgender, 
    "printrep": printrep }

Изменения значений, которые не сработали в вашем коде, теперь учитываются и работают хорошо:

# CHANGE AGE VALUES: 
arec['setage'](25)
brec['setage'](25)

# PRINT RECORDS: 
arec["printrep"]()
brec["printrep"]()

выход:

in setage fn; val rcd:  25
in setage fn; val rcd:  25
Name:  Ram
Age:  25
Gender:  M
===========================
Name:  Tom
Age:  25
Gender:  M
===========================
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...