标签: magic-methods

PHP 5.3 Magic Method __invoke

本主题扩展了什么时候/我应该在PHP中使用__construct(),__ get(),__ set()和__call()? 其中谈到了__construct,__get__set魔术方法.

从PHP 5.3开始,有一个新的魔术方法叫做__invoke.__invoke当脚本尝试将对象作为函数调用时,将调用该方法.

现在我已经为这种方法做过研究,人们把它比作Java方法.run()- 参见Interface Runnable.

经过长时间的努力思考,我无法想到为什么你会打电话$obj(); 而不是$obj->function();

即使您在一个对象数组上进行迭代,您仍然可以知道要运行的主函数名称.

那么__invoke魔术方法的另一个例子是'因为你可以,并不意味着你应该'在PHP中使用快捷方式,或者是否有这种情况实际上是正确的做法?

php oop magic-methods

27
推荐指数
4
解决办法
2万
查看次数

PHP子类Magic __isset有效,但__get没有

我有一个抽象的父类Mongo_Document(来自mongodb-php-odm)和一个继承的类Model_ActionPlan. Mongo_Document具有与Mongo_Document类内部数组交互的magic __isset和__get方法.

我试图使用以下代码(从方法内部的代码片段Model_ActionPlan):

if (isset($this->status))
{
    if (($this->status === "closed") AND ($this->close_type != "failure"))
    {
        return;
    }
}
Run Code Online (Sandbox Code Playgroud)

(注意,close_type如果是,则保证设置status == 'closed'.)

isset调用返回true,然后继续执行下一条语句.在那里,我收到以下错误:

 Undefined property: Model_ActionPlan::$status
Run Code Online (Sandbox Code Playgroud)

但是,如果我替换$this->statusparent::__get('status'),则此代码按预期工作.请注意,在程序的其他任何地方,我都可以使用:

$ap = new Model_ActionPlan($plan_id);
echo $ap->status;
// Prints 'closed' (or 'active') as expected
Run Code Online (Sandbox Code Playgroud)

只有在这里,在课堂内部,这不起作用.

我环顾四周,似乎无法找到任何说明在子类中无法调用魔法的方法.我可以使用该parent::__get调用,但我认为这可能是错误的方法.有谁知道是否有正确/更好的方法来做到这一点?

更新了#1 2012-12-16: 父类的完整代码在Github上.

更新了#2 2012-12-18: 对于询问设置在何处或是否设置正确的人,答案是,由于调用parent::__get('status') 确实有效,问题显然不是变量没有设置.它__get()是从一个名为的私有instace变量中获取数据的 …

php inheritance magic-methods mongodb-php

25
推荐指数
1
解决办法
1627
查看次数

赋值与定义 Python 魔术方法

考虑以下令人厌恶的类:

class MapInt:
    __call__ = int

    def __sub__(self, other):
        return map(self, other)

    __add__ = map
Run Code Online (Sandbox Code Playgroud)

然后可以map(int, lst)通过调用MapInt() - lst,即

assert list(MapInt() - ['1','2','3'])) == [1,2,3]    # passes
Run Code Online (Sandbox Code Playgroud)

然而,加法就不那么合作了:

assert list(MapInt() + ['1','2','3'])) == [1,2,3]    # TypeError: map() must have at least two arguments.
Run Code Online (Sandbox Code Playgroud)

这个奇怪的现象可以通过直接调用magic方法来解决:

assert list(MapInt.__add__(MapInt(), ['1','2','3']))   == [1,2,3]    # passes
assert list(MapInt().__add__(MapInt(), ['1','2','3'])) == [1,2,3]    # passes
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,什么给出了?直接赋值__add__似乎“丢弃”了self参数,但是调用方法本身或以标准方式定义它效果很好。

python class magic-methods assign

24
推荐指数
1
解决办法
2018
查看次数

如何使内联数组初始化工作,如字典初始化?

为什么可以这样初始化Dictionary<T1,T2>:

var dict = new Dictionary<string,int>() { 
    { "key1", 1 },
    { "key2", 2 }
};
Run Code Online (Sandbox Code Playgroud)

...但是不要以KeyValuePair<T1,T2>完全相同的方式初始化一组对象:

var kvps = new KeyValuePair<string,int>[] {
    { "key1", 1 },
    { "key2", 2 }
};
// compiler error: "Array initializers can only be used in a variable 
// or field initializer.  Try using a new expression instead."
Run Code Online (Sandbox Code Playgroud)

我意识到我可以通过new KeyValuePair<string,int>() { "key1", 1 }为每个项目编写等来使第二个例子工作.但我想知道是否可以使用第一个示例中可能的相同类型的简洁语法.

如果不可能,那么是什么让Dictionary类型如此特别?

c# syntax initialization magic-methods

21
推荐指数
2
解决办法
3442
查看次数

PHPDoc和__callStatic

TL;博士

注释(在PHPDoc中)通过实现的函数的正确方法是什么__callStatic?更重要的是:有没有办法让NetBeans PHPStorm理解这些是静态方法?

动机

如果你想要更大的图片,这就是我对这个问题的看法.

问题:在我目前的项目中,我们有很多类应该是单例(DB代理等).不用说,我们至少有几百require_once$foo = new FooProxy();线.

解决方案:我创建了一个Loader类来解决这个问题,使用__callStatic魔术方法,所以我们可以说$foo = Loader::FooProxy();.它非常适合我们的目的,但是:

问题:这种方式在团队中使用的IDE中显然没有类型提示.

解决方案:每个模块定义一个子类Loader,添加仅路由到的方法__callStatic.

问题:为了自动完成而添加实际解释的代码是不可接受的(这可以争论,但让我们暂时接受它).

解决方案:我们不添加任何实际方法,只需在PHPDoc中声明方法如下:

<?php
/**
 * @method FooProxy FooProxy()
 */
 class BarLoader extends Loader {}
?>
Run Code Online (Sandbox Code Playgroud)

问题:FooProxy不是静态方法.以下所有内容都不会使其成为静态:

<?php
/**
 * @static
 * @method FooProxy FooProxy()
 */

///////////////

/**
 * @static @method A A()
 * @method static A A()
 * @method A …
Run Code Online (Sandbox Code Playgroud)

php phpdoc magic-methods

20
推荐指数
1
解决办法
5863
查看次数

将字符串作为变量粘贴到IPython中,而不是作为可执行代码片段

我知道神奇的IPython %paste命令,如果你有有效的代码插入,这是非常有用的.现在我不想插入代码,我只想将复制缓冲区中的一些字符串存储为变量.有没有更简单的方法,除了将字符串复制到一些单独的文本编辑器并首先修改它?

像这样的东西会很好,但它们都不起作用:

strvar = %paste
strvar = """%paste"""
Run Code Online (Sandbox Code Playgroud)

PS字符串很长,包含特殊的字符等.所以简单的ctrl-c只会创建垃圾和错误消息.

python copy-paste ipython magic-methods

18
推荐指数
1
解决办法
3552
查看次数

即使方法存在,也在PHP中触发__call()

PHP文件说,下面讲__call()魔术方法:

在对象上下文中调用不可访问的方法时会触发__call().

__call()调用实际方法之前,即使方法存在,我是否可以调用?或者,是否有其他钩子我可以实现或提供此功能的另一种方式?

如果它很重要,这是为了static function(我实际上更愿意使用__callStatic).

php magic-methods

17
推荐指数
2
解决办法
1万
查看次数

操作符"is"和"in"的魔术方法名称是什么?

我想使用这些运算符的魔术方法进行bool二进制运算.例如,我可以得到a < b作为getattr(a, '__lt__')(b)a == b作为getattr(a, '__eq__')(b).

我能得到a in b并且a is b以这样的方式?

python magic-methods getattr

17
推荐指数
2
解决办法
1335
查看次数

有没有办法在Python中返回min和max的自定义值?

我有一个自定义类,

class A:
    def __init__(self, a, b):
        self.a = a
        self.b = b
Run Code Online (Sandbox Code Playgroud)

该类不可迭代或可索引或类似的东西.如果可能的话,我想保持这种方式.有可能像以下工作一样吗?

>>> x = A(1, 2)
>>> min(x)
1
>>> max(x)
2
Run Code Online (Sandbox Code Playgroud)

让我想到这一点的是,minmax文档中列为"通用序列操作" .由于range被同一个文档认为是序列类型,我认为必须有某种可能的优化range,也许我可以利用它.

也许有一种我不知道的神奇方法可以实现这一点吗?

python magic-methods python-3.x

17
推荐指数
3
解决办法
3096
查看次数

__new__ 方法给出错误对象。__new__() 只需要一个参数(要实例化的类型)

为什么下面的代码会出错?

class Foo:
    def __new__(cls, *args, **kwargs):
        print("Creating Instance")
        instance = super(Foo, cls).__new__(cls,*args, **kwargs)
        return instance

    def __init__(self, a, b):
        self.a = a
        self.b = b

z= Foo(2,3)
Run Code Online (Sandbox Code Playgroud)

它给出了以下错误

TypeError: object.__new__() takes exactly one argument (the type to instantiate)
Run Code Online (Sandbox Code Playgroud)

python magic-methods python-3.x

15
推荐指数
5
解决办法
6756
查看次数