我有以下代码(例如,实际上,这是我的真实代码):
<?php
class Foobar
{
public static function foo()
{
exit('foo');
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行$foobar = new FooBar; $foobar->foo()它显示foo.
为什么PHP会尝试在对象上下文中使用静态方法?有办法避免这种情况吗?
好吧,你们没有得到我的问题:我知道静态和非静态方法之间的区别以及如何调用它们.这是我的全部意义,如果我打电话$foobar->foo(),为什么PHP会尝试运行静态方法?
注意:我运行PHP 5.4.4,报告错误E_ALL.
>>> class Thing(object):
... def __index__(self):
... return 1
...
>>> thing = Thing()
>>> list_ = ['abc', 'def', 'ghi']
>>> list_[thing]
'def'
>>> dict_ = {1: 'potato'}
>>> dict_[thing]
# KeyError
Run Code Online (Sandbox Code Playgroud)
thing知道如何在列表访问时将自己表示为1,而不是由dict表示?难道两种魔术方法都没有通过__getitem__?列表中显示的用法可以通过,__int__所以无论如何,存在的理由是__index__什么?
我正在尝试创建一个对象代理。属性/属性查找可以通过简单地实现__getattribute__,__setattr__和__delattr__方法来完成。但是,其他功能如len(x), x[], bool(x)需要其他 dunder 方法__len__, __getitem__, __bool__来实现。如果您没有在代理类上实现这些,但是您代理的对象支持它们,您的代理将不完整并导致运行时错误。
因此,我想拥有一份我需要实施的所有事情的综合清单,但我在网上找不到任何可靠的清单。
这是我从typing和builtins模块中获得的 97 个独特的 dunder 方法名称。我知道他们中的很多人在做什么,但有些人我不知道。为我的代理类实现所有或大部分它们会很痛苦,所以如果有解决方法我会很高兴。
__abs__
__add__
__aenter__
__aexit__
__aiter__
__and__
__anext__
__await__
__bool__
__bytes__
__call__
__class__
__cmp__
__complex__
__contains__
__delattr__
__delete__
__delitem__
__delslice__
__dir__
__div__
__divmod__
__enter__
__eq__
__exit__
__float__
__floordiv__
__format__
__fspath__
__ge__
__get__
__getattribute__
__getitem__
__getnewargs__
__getslice__
__gt__
__hash__
__iadd__
__iand__
__import__
__imul__
__index__
__init__
__init_subclass__
__instancecheck__
__int__
__invert__
__ior__
__isub__
__iter__
__ixor__
__le__
__len__ …Run Code Online (Sandbox Code Playgroud) 我想使用接口,但我的一些实现依赖于魔术方法,如__invoke和__call.我必须从界面中删除可能被神奇地(在任何实现中)调用的方法的签名.这导致反模式空接口(是的,我刚刚做到了).
如何在PHP中结合接口和魔术方法?
我一般都试图远离PHP的魔术方法,因为它们似乎混淆了对象的公共接口.也就是说,至少在我读过的代码中,它们似乎被越来越多地使用了,所以我不得不问:对何时使用它们有什么共识?使用这三种魔术方法有什么共同的模式吗?
突击队需要你的帮助.
我在Yii有一个控制器:
class PageController extends Controller {
public function actionSOMETHING_MAGIC($pagename) {
// Commando will to rendering,etc from here
}
}
Run Code Online (Sandbox Code Playgroud)
我需要在Yii CController下使用一些神奇的方法来控制/ page ||下的所有子请求 页面控制器.
这是Yii的某种可能吗?
谢谢!
我肯定我早就读过PHP的一个新功能,它既可以是新的魔术方法,也可以是新的接口,这样你就可以实现Arrayable方法.
例如
interface Arrayable
{
public function toArray();
}
Run Code Online (Sandbox Code Playgroud)
我在想象吗?
我正在尝试创建一个Python属性,其中就地添加由不同的方法处理,而不是检索值,添加另一个值并重新分配.因此,对于x对象上的属性o,
o.x += 5
Run Code Online (Sandbox Code Playgroud)
应该不同于
o.x = o.x + 5
Run Code Online (Sandbox Code Playgroud)
最终的价值o.x应该是相同的,以免混淆人们的期望,但我想让就地增加更有效率.(实际上,操作比简单添加需要更多的时间.)
我的第一个想法是在课堂上定义
x = property(etc. etc.)
x.__iadd__ = my_iadd
Run Code Online (Sandbox Code Playgroud)
但这引发了一个AttributeError,大概是因为property工具__slots__?
我的下一次尝试使用描述符对象:
class IAddProp(object):
def __init__(self):
self._val = 5
def __get__(self, obj, type=None):
return self._val
def __set__(self, obj, value):
self._val = value
def __iadd__(self, value):
print '__iadd__!'
self._val += value
return self
class TestObj(object):
x = IAddProp()
#x.__iadd__ = IAddProp.__iadd__ # doesn't help
>>> o = TestObj()
>>> print o.x
5 …Run Code Online (Sandbox Code Playgroud) 我很困惑PHP中的"静态"和"动态"函数和对象如何协同工作,特别是关于__callStatic().
__callStatic()的工作原理如下:
你可以有一个普通的类MyClass,你可以在类中放置一个名为__callStatic()的静态函数,只有当MyClass没有你想要的名字的静态函数时才会调用它.
即我打电话
MyClass::newFunction();
newFunction()被静态调用,但MyClass没有声明它.所以,然后__callStatic()被调用,你可以说Run Code Online (Sandbox Code Playgroud)$myObject=new SomeOtherClass(); $myObject->newFunction();它调用你想要的函数但是在其他一些对象上.
精简版:
换句话说,__ callStatic()执行此操作:
MyClass::newFunction();
Run Code Online (Sandbox Code Playgroud)
这隐藏了这个:
(new SomeOtherClass())->newFunction();
Run Code Online (Sandbox Code Playgroud)
说什么呢?看起来代码从类中调用静态函数看起来就是从其他类调用该函数并通过实例化调用它,而不是静态调用.
请解释一下!
为什么这样做?你可以在其他地方做这样的事情,比如C++或Java吗?我正在寻找关于语言中静态和动态函数的简短而简洁但有用的解释,在这种情况下,无论是__callStatic()violates还是conforms语言结构的大图.或者它完全是一种新的语言结构.
有很多关于这个问题的SO问题,特别是这个问题,但它对我没有帮助.
有之间的模糊性property_exists和isset如此前问我的问题,我要指出来:
property_exists检查对象是否包含属性而不查看其值,它只查看其可见性.
所以在下面的例子中:
<?php
class testA
{
private $a = null;
}
class testB extends testA
{
}
$test = new testA();
echo var_dump(property_exists($test, 'a')); // true
// parent's private property becomes invisible for its child
$test = new testB();
echo var_dump(property_exists($test, 'a')); // false
Run Code Online (Sandbox Code Playgroud)
isset检查属性中是否存在值 如果值等于false,和,则设置为未设置null.
<?php
$var = null;
echo var_dump(isset($var)); // false
$var = '';
echo var_dump(isset($var)); // …Run Code Online (Sandbox Code Playgroud) magic-methods ×10
php ×7
interface ×2
properties ×2
python ×2
arrays ×1
casting ×1
descriptor ×1
isset ×1
proxy-object ×1
python-3.x ×1
static ×1
yii ×1