Access a method's local variables in Python
Was going through a Python Tutorial and have asked a related question here(Code from my previous example and thanks to @emmanuel)
Code:
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):
开发者_StackOverflow 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)
From this code, I tried to get the variable fnum which is local to the function(method) isprime, which contains the factor list. Accessing it by calling
print eg.isprime(num).fnum
gave me a error
AttributeError: 'tuple' object has no attribute 'fnum'
I guess I cannot call a local variable that way.
Plus the code is not reusable. So I decided to do a rewrite, to make it more modular.
Rewritten Code:
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)
I had to forgo time calculation. I can calculate time while using an instance.
Question:
Can I access the local variable fnum
in my previous example? If yes, How?(I guess no). If no, then is the rewritten code good enough or am I doing it wrong?
The problem with your modification is that you're duplicating the calculus. I understand you just want to get the calculated factors, which just involves creating fnum as an attribute:
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()
You could even develop the code a little bit more and take advantage of the previous calculated factors, thus using dynamic programming.
Hope this helps.
You need:
print eg.isprime(num)[2]
(your method is returning a tuple, and you need the third member, that's all)
There is no way to access the local variables of a function from outside that function. You need to explicitly make them available to callers, either by returning them, or by writing their values into a container available to the caller.
精彩评论