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风格的方法。我的解决方案变成了这个方案和评论中建议的方案的混合体。