Python 如何确保在调用另一个类函数之前不会调用该类函数?
我有一个类对象,它创建了一些数据字段:Python 如何确保在调用另一个类函数之前不会调用该类函数?,python,python-2.7,Python,Python 2.7,我有一个类对象,它创建了一些数据字段: class DataFields(object): _fields_ = ['field_1', 'field_2', 'data_length'] def __init__(self, data=None): if data != None: self.create_fields(data) def create_fields(self, data): i = 0
class DataFields(object):
_fields_ = ['field_1', 'field_2', 'data_length']
def __init__(self, data=None):
if data != None:
self.create_fields(data)
def create_fields(self, data):
i = 0
for field in self._fields_:
setattr(self, field, data[i])
i += 1
def get_datalength(self):
return self.data_length
确保除非创建了data\u length
字段(即,除非调用了create\u fields()
函数),否则无法调用get\u datalength()
函数的最佳方法是什么
我考虑过使用在
create\u字段中初始化并在get\u datalength()
中签入的变量,或者在get\u datalength()函数中使用try except
。最具python风格(或最佳)的方式是什么?通过使用默认值的getattr
,您可以返回None
,或者如果实例中还没有data\u length
属性,则返回任何值:
def get_datalength(self):
return getattr(self, 'data_length', None)
我认为最具python风格的方式是抛出一个异常:
def get_datalength(self):
try:
return self.data_length
except AttributeError:
raise AttributeError("No length call create_fields first")
原因很简单:无法阻止用户对对象调用此函数。用户可能会得到一个AttributeError
,无法理解发生了什么,或者您提供了自己的错误类或至少是错误消息
顺便说一句:
它不是pythonic创建getter方法(没有“私有成员”之类的东西)
如果需要对返回的值执行较小的操作,请查看@属性
装饰器
@property
def datalength(self):
return do_some_stuff(self.data_length)
使用异常可能是您正在执行的操作的最佳方式,但是如果您将从交互式控制台使用此对象,则有一些替代方法可能会很有用:
def fn2(self):
print("this is fn2")
class test:
def fn1(self):
print("this is fn1")
self.fn2 = fn2
def fn2(self): # omit this if you want fn2 to only exist after fn1 is called
print("Please call fn1 first")
我不建议每天都使用它,但在某些情况下它会很有用。如果省略在类中定义fn2,那么方法fn2将仅在调用fn1后出现。为便于代码维护,您可以执行以下操作:
class test:
def fn1(self):
print("this is fn1")
self.fn2 = self._fn2
def _fn2(self):
print("this is fn2")
def fn2(self): # omit this if you want fn2 to only exist after fn1 is called
print("Please call fn1 first")
如果要在将要导入的模块中使用此选项,则应引发异常或像其他答案所建议的那样返回有效值。这可以通过将字典作为类变量,并将方法名称作为键来解决
called['method1']
called['method2']
called['method3']
...
并在该方法调用中设置键
class SomeClass(obj):
def method1():
called['method1'] = 1
def method2():
if method1 in called:
# continue
最好的方法可能是让create_fields
使用所需的适当方法返回一个新对象。不要试图在一节课上做所有的事情。我想这正是我需要做的。谢谢你的提示!在上面。。。。是否有理由允许在初始化后运行create_字段?如果删除数据的默认值,那么它总是保证存在,因为它总是在init期间运行。在完整的代码中,\u fields\u
是一个二维数组,它还包括数据字段的格式,在创建字段之前,我使用这些格式来解压数据。因此,我相信@roippi为我提供了最好的解决方案。这很好-您仍然可以在\uuuu init\uuuu
中这样做。将它们分开(不需要创建字段)的唯一原因是,如果您有一些用例,您可以创建一个空白对象,将其保留一段时间,然后稍后向其添加数据。顺便说一句,对于异常方法,您根本不需要任何东西。。。如果用户试图访问myobject.field1
,但该字段尚未创建,如果该值存在,则该字段将返回该值;如果该值不存在,则返回AttributeError
。不过,最好能更好地解释错误所在。您可以在不丢失堆栈跟踪的情况下执行此操作,例如:除了AttributeError作为e:e.args=(“无属性'length';首先调用create_fields”);raise
我认为这确实是最具python风格的方法。我的解决方案变成了这个方案和评论中建议的方案的混合体。