在Python中访问方法的局部变量

0 投票
3 回答
2077 浏览
提问于 2025-04-16 10:35

我在学习Python教程的时候,遇到了一个相关的问题,之前的代码来自于我的一个例子,感谢@emmanuel的帮助。

代码:

import math, time
class PrimeFactor:
    def __init__(self):
        pass
    def isprime(self,number):
        start=time.clock()
        fnum = [1,]
        print "Reticulating Splines..."
        last = int(math.ceil(math.sqrt(number)))
        for p in range(2, last + 1):
            if (number % p) == 0:
                fnum.append(p)
                fnum.append(number / p)
        # Remove duplicates, sort list
        fnum = list(set(fnum))
        fnum.sort()
        end=time.clock()
        if len(fnum) > 1:
            return number, "is not a prime because of these factors", fnum ,"Time taken", end-start
        else:
            return True, "Time taken", end-start

print "Prime or factor calculator v3 using sqrt(n)"
print #

num =int(raw_input("Enter number: "))
eg=PrimeFactor()

print eg.isprime(num)

从这段代码中,我想获取一个叫做fnum的变量,它是isprime这个函数内部的局部变量,里面存储了因子列表。通过调用

print eg.isprime(num).fnum

我得到了一个错误。

AttributeError: 'tuple' object has no attribute 'fnum'    

我想我不能那样调用局部变量。

而且这段代码也不够灵活,所以我决定重写一下,让它更模块化。

重写后的代码:

import math
class PrimeFactor:
    def __init__(self):
        pass
    def isPrime(self,number):
        fnum = [1,]
        last = int(math.ceil(math.sqrt(number)))
        for p in range(2, last + 1):
            if (number % p) == 0:
                return False
            else:
                return True
    def getFactors(self,number):
        fnum = [1,]
        last = int(math.ceil(math.sqrt(number)))
        for p in range(2, last + 1):
            if (number % p) == 0:
                fnum.append(p)
                fnum.append(number / p)
        # Remove duplicates, sort list
        fnum = list(set(fnum))
        fnum.sort()
        if len(fnum) > 1:
            return fnum
        else:
            return None


num =int(raw_input("Enter number: "))
eg=PrimeFactor()

if eg.isPrime(num):
    print num, "is a Prime Number"
else:
    print num, "is not a prime number"
    print "Factors", eg.getFactors(num)

我不得不放弃时间计算。其实我可以在使用实例的时候再计算时间。

问题:

我能在之前的例子中访问局部变量 fnum 吗?如果可以,怎么做?(我猜不可以)。如果不可以,那重写后的代码够好吗?还是我做错了什么?

3 个回答

2

你不能从函数外部直接访问函数里面的局部变量。要想让外部能够使用这些变量,你得明确地把它们提供给外部,比如通过返回这些变量的值,或者把它们的值写入一个外部可以访问的容器里。

3

你需要:

print eg.isprime(num)[2]

(你的方法返回的是一个元组,而你只需要里面的第三个元素,仅此而已)

3

你修改的地方有个问题,就是你在重复计算。其实我明白你只是想得到计算出来的结果,这样的话只需要把fnum作为一个属性来创建就可以了:

import math, time
class PrimeFactor:
    def __init__(self):
        self.fnum = [1,]
        self.elapsedTime = 0
    def getElapsedTime(self):
        return self.elapsedTime
    def getFactors(self):
        return self.fnum
    def isprime(self,number):
        start=time.clock()
        self.fnum = [1,]
        last = int(math.ceil(math.sqrt(number)))
        for p in range(2, last + 1):
            if (number % p) == 0:
                self.fnum.append(p)
                self.fnum.append(number / p)
        # Remove duplicates, sort list
        self.fnum = list(set(self.fnum))
        self.fnum.sort()
        end=time.clock()
        self.elapsedTime = end-start
        return (not len(self.fnum) > 1 )

num =int(raw_input("Enter number: "))
eg=PrimeFactor()

if eg.isprime(num):
    print num, "is a Prime Number", eg.isprime(num)
else:
    print num, "is not a prime number"
    print "Factors", eg.getFactors()
print eg.getElapsedTime()

你甚至可以把代码再改进一下,利用之前计算出来的结果,这样就可以用动态规划的方法了。

希望这对你有帮助。

撰写回答