Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中调用时,是否可以创建一个不存在的方法?_Python - Fatal编程技术网

在Python中调用时,是否可以创建一个不存在的方法?

在Python中调用时,是否可以创建一个不存在的方法?,python,Python,如果我有这门课: class MyClass(object): pass 然后我就这么做了: instance = MyClass() instance.new_method() 我得到了一个AttributeError异常,但我希望以友好方式创建此方法并返回一个特殊的IFC值。可能吗?是的,您可以通过以下方式进行操作: class MyClass(object): pass def some_method(): pass name = 'new_method'

如果我有这门课:

class MyClass(object):
   pass
然后我就这么做了:

instance = MyClass()
instance.new_method()
我得到了一个AttributeError异常,但我希望以友好方式创建此方法并返回一个特殊的IFC值。可能吗?

是的,您可以通过以下方式进行操作:

class MyClass(object):
   pass

def some_method():
    pass

name = 'new_method'    

setattr(MyClass, name, classmethod(some_method))

首先,Python检查是否存在具有该名称的属性,如果存在,它将调用该属性。没有明确的方法提前检测是否调用此属性

以下是实现您所需的棘手方法:

class Dispatcher(object):

    def __init__(self, caller, name):
        self.name = name
        self.caller = caller

    def __call__(self, *a, **ka):
        print('Call on Dispatcher registered!', 
              'Will create method on',
              self.caller.__class__.__name__,
              'now.')
        setattr(self.caller, self.name, self.mock)
        return getattr(self.caller, self.name)(*a, **ka)

    @classmethod
    def mock(cls, *a, **ka):
        return 'Some default value for newly created methods.'


class MyClass(object):

    def __getattr__(self, attr):
        return Dispatcher(self, attr)


instance = MyClass()
print(instance.new_method, '\n')
print(instance.new_method(), '\n')
print(instance.new_method(), '\n')
print(instance.other_method)
输出:

<__main__.Dispatcher object at 0x0000000002C07DD8> 

Call on Dispatcher registered! Will create method on MyClass now.
Some default value for newly created methods. 

Some default value for newly created methods. 

<__main__.Dispatcher object at 0x0000000002C07DD8>

呼叫调度员!现在将在MyClass上创建方法。
新创建的方法的一些默认值。
新创建的方法的一些默认值。
尽管此解决方案非常全面,但每次尝试访问不存在的属性时,它都会返回
Dispatcher
的新实例

如果调用了
Dispatcher
实例(例如
Dispatcher(self,attr)(
),它会将
mock
作为名为
attr
的新方法设置到对象,作为第一个参数传递给构造函数。

这是可能的

>>> class MyClass(object):
        pass

>>> instance = MyClass()
>>> def new_method(cls, x):
        print x


>>> MyClass.new_method = new_method
>>> instance.new_method(45)
45

请注意,
new\u方法
cls
作为第一个参数,当作为实例方法调用时,(实例)会隐式传递该参数。

是的,但可能有更好的方法来解决此问题。您能否深入了解为什么要这样做?您的限制是什么?非常感谢!但是,您知道如何判断调用的是方法还是属性吗?比如,我可以知道它是名为instance.new_method还是名为instance.new_method()。因为,attr的值是相同的=/@rafaels88您需要属性还是方法?我只需要获得新方法并创建它们。但是,如果它是一个属性,我什么也不做。@rafaels88实际上,当你调用一个方法时,Python首先检查它是否存在,没有简单直接的方法来检查它是属性还是方法如果我没有弄错的话,这个解决方案只会将该方法设置为函数属性。正如问题所要求的,它不会在调用时创建方法。为什么
cls
而不是通常的
self
?通常,当方法定义位于类定义内时,我使用
self
。这里的
new\u method()
是一个独立的方法<不过,代码>实例更合适。“实际上,这只是一种偏好。”哈耶姆小姐。我之所以问这个问题,是因为当实例是类时,通常使用
cls
,类方法和
type也是如此。使用
self
的另一个原因是,从技术上讲,它可以作为关键字传入,即使实际上几乎从未这样做过。