Python:方法 X 实例 class A 并调用方法 E。当此 class 被实例化时,它再次调用方法 X。怎么解决好呢?
Python: Method X instances class A and calls method E. When this class is instanced it calls method X again. How to solve it in a good way?
嗯,整个问题都在问题标题中描述了。正如你们所看到的,我在打电话时遇到了这个问题。
顺便说一句,考虑到我已经导入了所有需要的库和 classes。
检查下面我的代码:
class PyUtility(object):
#@Arguments:
#path = file path to be opened
#op = mode in which the file will be opened, r+ by default
#Return: A file for writing or reading, depending on the value of op variable
def loadPath(self, path, op='r+'):
print 'loadPath()'
try:
#In case the path string is '/example/example', instead of 'example/example'
if path[0] == '/':
path = path.lstrip('/')
return open(path, op)
except Exception, e:
print 'A new file has been created!'
directories = path.split("/")
#In case the path string is '/example/example', instead of 'example/example'
if directories[0] == '':
directories.pop(0)
#Retrieving the file to be loaded, it is the last one in the list
fileName = directories.pop()
newPath = ''
#In case the file is to be created in the root folder there will be no iteration, therefore frk will be empty
frk = ''
for directory in directories:
frk = '/'
#Browsing through the directories and creating them if necessary
newPath = newPath + directory
if not os.path.exists(newPath):
os.makedirs(newPath)
newPath = newPath + frk
newPath = newPath + frk + fileName
#Here it lies the problem... The method X (loadPath) will instance class A (Log) and call method E (error)
Log().error(e)
return open(newPath, 'w')
class Log(object):
#Opens all log files and loads the current number of lines for each
def __init__(self):
errors_path = "logs/"+strftime("%Y-%m-%d", gmtime())+"/errors_log.txt"
#Now that the class is being instanced it calls method X (loadPath) again
self.errors_log = PyUtility().loadPath(errors_path)
self.errors_log.seek(0,2)
def error(self, e):
self.errors_log.write("Error ["+str(self.errors_count)+"] @ "+strftime("%Y:%m:%d:%H:%M:%S", gmtime())+": "+str(e)+"\n")
self.errors_count = self.errors_count + 1
我的部分解决方案并不令我满意,我在 Log class 中创建了另一个 "loadPath" 方法,我只是将其命名为 "loadLog" 并且它工作正常。但是我想知道是否还有其他选择。
干杯[]'
是的,有一个简单的解决方案。
就我个人而言,我喜欢让方法尽量简短。我并不是说您必须遵循我的个人喜好才能发挥作用,但在我看来,有一种非常简单的方法可以解决此类问题。每当一个函数开始变得像 def loadPath()
这样大(我知道有些人会说它很小)时,您很有可能可以很好地重构它。我对 big 的定义是实现细节与意图的比例过高。换句话说,我倾向于 declarative programming.
那现在呢?
简单。只是重构它。
import os
class PyUtility(object):
def loadPath(self, path, op='r+'):
print 'loadPath()'
try:
return open(path.lstrip('/'), op)
except Exception, e:
Log().error(e)
return open(createvalidpath(path), 'w')
def createvalidpath(path):
directories = path.split("/")
#In case the path string is '/example/example', instead of 'example/example'
if directories[0] == '':
directories.pop(0)
#Retrieving the file to be loaded, it is the last one in the list
fileName = directories.pop()
newPath = ''
#In case the file is to be created in the root folder there will be no iteration, therefore frk will be empty
frk = ''
for directory in directories:
frk = '/'
#Browsing through the directories and creating them if necessary
newPath = newPath + directory
if not os.path.exists(newPath):
os.makedirs(newPath)
newPath = newPath + frk
return newPath + frk + fileName
class Log(object):
#Opens all log files and loads the current number of lines for each
def __init__(self):
errors_path = "logs/"+strftime("%Y-%m-%d", gmtime())+"/errors_log.txt"
self.errors_log = (
open(errors_path, 'w') if os.path.isfile(errors_path)
else open(createvalidpath(errors_path), 'w')
)
self.errors_log.seek(0,2)
def error(self, e):
self.errors_log.write("Error ["+str(self.errors_count)+"] @ "+strftime("%Y:%m:%d:%H:%M:%S", gmtime())+": "+str(e)+"\n")
self.errors_count = self.errors_count + 1
你看,createvalidpath
现在只是一个模块级函数(为什么不呢?)。没有什么说函数必须都是 class 的一部分。毕竟,似乎它可能会从许多不同的地方被调用。如果最终你得到了一组执行文件路径操作的相关函数,并且如果它们应该共享状态是有意义的,那么创建一个新的 class
并从那里开始。
避免循环调用
如您所见,Log
可以安全地调用 createvalidpath
如果需要 。只有 loadPath
需要记录错误,而不是 createvalidpath
。所以,本质上,这两个函数都执行一个具体的动作、意图等。当你写一个长函数时这样想:Is there a good chance that buried in this function I may have to re - 单独使用它的一部分? 如果是,重构它。
顺便说一下,这个位是不必要的...
if path[0] == '/':
path = path.lstrip('/')
我改成了:
return open(path.lstrip('/'), op)
因为最终如果前面没有 '/'
,它会 return 结果原样。好处是您可以进一步简化代码。
嗯,整个问题都在问题标题中描述了。正如你们所看到的,我在打电话时遇到了这个问题。
顺便说一句,考虑到我已经导入了所有需要的库和 classes。
检查下面我的代码:
class PyUtility(object):
#@Arguments:
#path = file path to be opened
#op = mode in which the file will be opened, r+ by default
#Return: A file for writing or reading, depending on the value of op variable
def loadPath(self, path, op='r+'):
print 'loadPath()'
try:
#In case the path string is '/example/example', instead of 'example/example'
if path[0] == '/':
path = path.lstrip('/')
return open(path, op)
except Exception, e:
print 'A new file has been created!'
directories = path.split("/")
#In case the path string is '/example/example', instead of 'example/example'
if directories[0] == '':
directories.pop(0)
#Retrieving the file to be loaded, it is the last one in the list
fileName = directories.pop()
newPath = ''
#In case the file is to be created in the root folder there will be no iteration, therefore frk will be empty
frk = ''
for directory in directories:
frk = '/'
#Browsing through the directories and creating them if necessary
newPath = newPath + directory
if not os.path.exists(newPath):
os.makedirs(newPath)
newPath = newPath + frk
newPath = newPath + frk + fileName
#Here it lies the problem... The method X (loadPath) will instance class A (Log) and call method E (error)
Log().error(e)
return open(newPath, 'w')
class Log(object):
#Opens all log files and loads the current number of lines for each
def __init__(self):
errors_path = "logs/"+strftime("%Y-%m-%d", gmtime())+"/errors_log.txt"
#Now that the class is being instanced it calls method X (loadPath) again
self.errors_log = PyUtility().loadPath(errors_path)
self.errors_log.seek(0,2)
def error(self, e):
self.errors_log.write("Error ["+str(self.errors_count)+"] @ "+strftime("%Y:%m:%d:%H:%M:%S", gmtime())+": "+str(e)+"\n")
self.errors_count = self.errors_count + 1
我的部分解决方案并不令我满意,我在 Log class 中创建了另一个 "loadPath" 方法,我只是将其命名为 "loadLog" 并且它工作正常。但是我想知道是否还有其他选择。
干杯[]'
是的,有一个简单的解决方案。
就我个人而言,我喜欢让方法尽量简短。我并不是说您必须遵循我的个人喜好才能发挥作用,但在我看来,有一种非常简单的方法可以解决此类问题。每当一个函数开始变得像 def loadPath()
这样大(我知道有些人会说它很小)时,您很有可能可以很好地重构它。我对 big 的定义是实现细节与意图的比例过高。换句话说,我倾向于 declarative programming.
那现在呢?
简单。只是重构它。
import os
class PyUtility(object):
def loadPath(self, path, op='r+'):
print 'loadPath()'
try:
return open(path.lstrip('/'), op)
except Exception, e:
Log().error(e)
return open(createvalidpath(path), 'w')
def createvalidpath(path):
directories = path.split("/")
#In case the path string is '/example/example', instead of 'example/example'
if directories[0] == '':
directories.pop(0)
#Retrieving the file to be loaded, it is the last one in the list
fileName = directories.pop()
newPath = ''
#In case the file is to be created in the root folder there will be no iteration, therefore frk will be empty
frk = ''
for directory in directories:
frk = '/'
#Browsing through the directories and creating them if necessary
newPath = newPath + directory
if not os.path.exists(newPath):
os.makedirs(newPath)
newPath = newPath + frk
return newPath + frk + fileName
class Log(object):
#Opens all log files and loads the current number of lines for each
def __init__(self):
errors_path = "logs/"+strftime("%Y-%m-%d", gmtime())+"/errors_log.txt"
self.errors_log = (
open(errors_path, 'w') if os.path.isfile(errors_path)
else open(createvalidpath(errors_path), 'w')
)
self.errors_log.seek(0,2)
def error(self, e):
self.errors_log.write("Error ["+str(self.errors_count)+"] @ "+strftime("%Y:%m:%d:%H:%M:%S", gmtime())+": "+str(e)+"\n")
self.errors_count = self.errors_count + 1
你看,createvalidpath
现在只是一个模块级函数(为什么不呢?)。没有什么说函数必须都是 class 的一部分。毕竟,似乎它可能会从许多不同的地方被调用。如果最终你得到了一组执行文件路径操作的相关函数,并且如果它们应该共享状态是有意义的,那么创建一个新的 class
并从那里开始。
避免循环调用
如您所见,Log
可以安全地调用 createvalidpath
如果需要 。只有 loadPath
需要记录错误,而不是 createvalidpath
。所以,本质上,这两个函数都执行一个具体的动作、意图等。当你写一个长函数时这样想:Is there a good chance that buried in this function I may have to re - 单独使用它的一部分? 如果是,重构它。
顺便说一下,这个位是不必要的...
if path[0] == '/':
path = path.lstrip('/')
我改成了:
return open(path.lstrip('/'), op)
因为最终如果前面没有 '/'
,它会 return 结果原样。好处是您可以进一步简化代码。