PHP中是否有一个魔术方法,每次调用另一个方法时都会调用它?__callStatic()和__call()魔术方法似乎只在方法不存在时才起作用.
我只是想使用描述符模式,但它似乎没有那么好用.这是一个简短的例子(没有任何实际用途,只是为了展示):
class Num(object):
def__init__(self, val=0):
self.val = val
def __get__(self, instance, owner):
return self.val
def __set__(self, instance, val):
self.val = val
def __str__(self):
return "Num(%s)" % self.val
def __repr__(self):
return self.__str__()
class Test(object):
def __init__(self, num=Num()):
self.num = num
Run Code Online (Sandbox Code Playgroud)
和测试:
>>>t = Test()
>>>t.num # OK
Num(0)
>>>t.num + 3 #OK i know how to fix that, but I thought __get__.(t.num, t, Test) will be called
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand …Run Code Online (Sandbox Code Playgroud) 我有一个自定义类,如:
class foo(object):
def __init__(self, name):
self.__name = name
def get_name(self):
return self.__name
Run Code Online (Sandbox Code Playgroud)
我想做的是写
test = foo("test")
print test
Run Code Online (Sandbox Code Playgroud)
代替
test = foo("test")
print test.get_name()
Run Code Online (Sandbox Code Playgroud)
这样做的神奇方法是什么?
在 python 中,如果我想创建一个对象,该对象在传递给特定函数时执行某些操作,我该怎么做?例如:
import logging
class TestObject:
def __logging__(self):
# It would check the calling function here and return something
# if it was a log function call from a logging class log function call
return 'Some text'
Run Code Online (Sandbox Code Playgroud) 我试图将魔术方法装饰__getitem__成课堂上的类方法.这是我尝试的样本.我不介意使用classmethod或staticmethod装饰,但我不太清楚如何做到这一点.这是我尝试过的:
import ConfigParser
class Settings(object):
_env = None
_config = None
def __init__(self, env='dev'):
_env = env
# find the file
filePath = "C:\\temp\\app.config"
#load the file
_config = ConfigParser.ConfigParser()
_config.read(filePath)
@classmethod
def __getitem__(cls, key):
return cls._config.get(cls._env, key)
@classmethod
def loadEnv(cls, env):
cls._env = env
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试调用时,Settings['database']我收到以下错误.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: expected Array[Type], got str
Run Code Online (Sandbox Code Playgroud)
谁能告诉我我做错了什么.此外,有人可以建议是否有更好的方法来做到这一点?我甚至尝试过使用MetaClasses,但收效甚微(因为我不太了解python).
class Meta(type):
def __getitem__(*args):
return type.__getitem__(*args)
class Settings(object):
__metaclass__ = Meta
Run Code Online (Sandbox Code Playgroud)
提前致谢.
我在codeigniter中有一个类,它只处理ajax.我在这个类中创建了一个函数来检查refferal是否是一个ajax refferal,我想每次使用这个类中的任何函数时都能调用这个函数.
因此我实施了__call魔术方法
class Ajax_content extends Controller {
function __construct()
{
parent::Controller();
}
function __call($method, $arguments){
$this->ajaxCheck(); //set up to return false and exit.
call_user_func_array(array($this,"_".$method),$arguments);
}
Run Code Online (Sandbox Code Playgroud)
目前ajaxCheck()总是回归false和exit()s.但它没有被调用(目前我的ajax请求仍然返回数据)这是解决问题的有效方法吗?
其他语言的一个便利功能是能够为属性创建get和set方法.在试图找到一种在PHP中复制此功能的好方法时,我偶然发现了这一点:http: //www.php.net/manual/en/language.oop5.magic.php#98442
这是我对该课程的细分:
<?php
class ObjectWithGetSetProperties {
public function __get($varName) {
if (method_exists($this,$MethodName='get_'.$varName)) {
return $this->$MethodName();
} else {
trigger_error($varName.' is not avaliable .',E_USER_ERROR);
}
}
public function __set($varName,$value) {
if (method_exists($this,$MethodName='set_'.$varName)) {
return $this->$MethodName($value);
} else {
trigger_error($varName.' is not avaliable .',E_USER_ERROR);
}
}
}
?>
Run Code Online (Sandbox Code Playgroud)
我的计划是扩展这个类get_someproperty()并set_someproperty()在这个扩展类中定义适当的.
<?php
class SomeNewClass extends ObjectWithGetSetProperties {
protected $_someproperty;
public function get_someproperty() {
return $this->_someproperty;
}
}
?>
Run Code Online (Sandbox Code Playgroud)
麻烦的是,基类ObjectWithGetSetProperties是无法看到我的方法get_someproperty()在SomeNewClass.我总是得到错误,"密钥不可用".
有没有办法解决这个问题,允许基类ObjectWithGetSetProperties …
这是上下文:
$values = $form->getValues();
foreach($values as $key=>$value) {
$obj->{$key} = $value;
}
Run Code Online (Sandbox Code Playgroud)
如果$key是有效密钥,__set($name, $value)则不会被调用.如果$key不是有效密钥,则为.这是我的集合的样子:
public function __set($name, $value) {
$method = 'set' . ucfirst($name);
if(method_exists($method)) {
$this->$method($value);
} else {
throw new RuntimeException('Attempt to access a non-existant property with method ' . $method);
}
}
Run Code Online (Sandbox Code Playgroud)
在该__set($name, $value)方法所属的对象中,所有属性都是私有的并且是下划线的.因此对于关键'名称',将有以下内容:
private $_name;
public function setName($name) {
$this->_name = $name;
return $this;
}
Run Code Online (Sandbox Code Playgroud)
我知道它没有被调用,因为我尝试在之后插入一个异常$method = 'set' . ucfirst($name);.当$name没有引用有效的setter时会触发该异常,但是当它没有引用时就没有被触发.它应该每次都被击中.任何人都知道这里发生了什么?
我非常喜欢"魔术方法"的语法或者在Python中调用的任何语法,比如
class foo:
def __add__(self,other): #It can be called like c = a + b
pass
Run Code Online (Sandbox Code Playgroud)
电话
c = a + b
Run Code Online (Sandbox Code Playgroud)
然后被翻译成
a.__add__(b)
Run Code Online (Sandbox Code Playgroud)
是否有可能模仿"非魔法"功能的这种行为?在数值计算中,我需要Kronecker产品,并且渴望拥有"kron"功能
kron(a,b)
Run Code Online (Sandbox Code Playgroud)
实际上是
a.kron(b)?
Run Code Online (Sandbox Code Playgroud)
用例是:我有两个类似的类,比如,矩阵和向量,都有Kronecker产品.我想打电话给他们
a = matrix()
b = matrix()
c = kron(a,b)
a = vector()
b = vector()
c = kron(a,b)
Run Code Online (Sandbox Code Playgroud)
矩阵和向量类在一个.py文件中定义,因此共享公共命名空间.那么,实现上述功能的最佳(Pythonic?)方式是什么?可能的解决方案:
1)有一个kron()函数并进行类型检查
2)具有不同的名称空间
3)?
我想使用__call方法通过另一个类属性调用类的方法(方法名称是动态决定的).我尝试如下.我希望代码能描述我的尝试.
class A {
public function a1($r1) { return 'a1.'; }
public function a2($r1, $r2) { return 'a2.'; }
//...
}
class B {
private $a;
function __construct() { $this->a = new A(); }
function __call($name, $args) {
// some code goes here.
// How to call the method of class-A using the property a.
return call_user_func_array('$this->a->'.$name, $args);
}
}
$b = new B();
// I want to call a1 and a2 of class-A through class-B.
echo $b->a1(11);
echo $b->a2(21, …Run Code Online (Sandbox Code Playgroud) magic-methods ×10
php ×5
python ×5
oop ×2
ajax ×1
codeigniter ×1
decorator ×1
descriptor ×1
function ×1
inheritance ×1
python-2.7 ×1