将简单函数用作具有OOP功能的类

时间:2019-06-14 07:32:06

标签: python function class oop

看到非常有趣的代码here,我正在尝试将Function作为类与以下代码一起使用:

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 个答案:

答案 0 :(得分:3)

当您尝试设置这些值时,请参考global变量。不过,您真正要更改的变量不是 global ,它们在CF_ptrec的范围内。您需要改用nonlocal age。当前,您正在设置 global 变量age,但正在从age范围读取 CF_ptrec

答案 1 :(得分:-1)

以@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
===========================