我最近与另一位开发人员就 PHP__isset()和__get()魔术方法之间的关系进行了简短的讨论。它是由我们拥有的一个类带来的,该类通过该__get()方法延迟加载其他对象(延迟加载意味着该属性在第一次访问之前不存在,此时对象被实例化并返回)。__isset()但是,对于尚未加载的属性应该返回什么,我们有不同的意见。该属性在技术上不存在(它不是set,或者至少,它是 set 但当前NULL),但是对它的调用在技术上也会成功(除非有任何异常)并返回一个非NULL值。
所以,我的问题是,在这种情况下,应该__isset()只是一个指示是否__get()会成功的同一个论点(TRUE如果__get()会成功,返回一个非NULL值)。或者,它是否应该在技术上表现得更好,并返回FALSE,因为数据尚不存在(即使第一次访问时它会存在)?
一个简单的例子:
class Foo {
protected $data;
public function __get($prop) {
if ($prop == 'bar') {
$this->data['bar'] = new Bar;
return $this->data['bar'];
}
}
public function __isset($prop) {
if ($prop == 'bar') {
// What goes here?
// return isset($this->data[$prop]) would mean
// that the first call to …Run Code Online (Sandbox Code Playgroud) 现在我有一个 BaseObject 可以对 DB 执行 ORM。我依靠私有 $data 和魔法 setter 和 getter 来创建带有一堆列的对象作为私有对象成员(动态)。在子类中,如果我想更改行为以设置单个对象成员,我必须覆盖父 setter 并查找键。我的问题是是否有更好的方法来做到这一点,我可以只覆盖单个对象成员而不是通过 __setter
映射到数据库并动态创建一堆私有参数的基本对象映射器
class Base
{
private $data = array();
public function __construct(){
//get columns info from db and do set
}
public function __set($key, $value){
$this->data[$key] = $value;
}
public function __get($key){
return isset($this->data[$key])? $this->data[$key] : null;
}
}
Run Code Online (Sandbox Code Playgroud)
和儿童班。现在要覆盖参数设置我必须这样做
class Child extends Base
{
public function __set($name, $value){
if($name == 'dog' && $value == 'chihuahua')
$this->dog = 'dog bark wolf wolf';
else if($name == 'cat' …Run Code Online (Sandbox Code Playgroud) 我在谷歌上搜索这些方法的任何用例或示例,但找不到任何详细解释,它们只是与其他类似方法一起列出。实际上,我在 github 上查看了一些代码并遇到了这些方法,但无法理解用法。有人可以提供这些方法的详细解释。这是我遇到它们的 github 代码链接:https : //github.com/msiemens/tinydb/blob/master/tinydb/queries.py
我试图使我的类作为另一个对象出现,以规避正在使用的程序包中的惰性类型检查。更具体地说,我试图使我的对象作为另一个对象的实例出现(tuple在我的情况下),而实际上它甚至不是该对象的派生。
为了实现这一目标,我计划重写该__isinstance__方法,根据docs,该方法应该完全按照我的意愿进行。但是,由于我的尝试未成功,因此我似乎不知道该怎么做。
这是一个SSCCE,应该在所有情况下都可以isinstance回报False,但不能回报。
class FalseInstance(type):
def __instancecheck__(self, instance):
return False
class Foo(metaclass=FalseInstance):
pass
g = Foo()
isinstance(g, Foo)
> True
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
我有以下课程:
from __future__ import print_function
class Proxy(object):
__slots__ = ['_value']
def __init__(self, obj):
self._value = obj
def __hex__(self):
return hex(self._value)
print(hex(42))
print(hex(Proxy(42)))
Run Code Online (Sandbox Code Playgroud)
在 Python 2.7 中,这会打印
(py2.7) c:\hextest> python hextest.py
0x2a
0x2a
Run Code Online (Sandbox Code Playgroud)
但在 Py3.8 中,这引发了一个例外:
(py3.8) c:\hextest> python hextest.py
0x2a
Traceback (most recent call last):
File "hextest.py", line 14, in <module>
print(hex(Proxy(42)))
TypeError: 'Proxy' object cannot be interpreted as an integer
Run Code Online (Sandbox Code Playgroud)
我需要实现什么才能使 Proxy 被解释为整数?
我想创建一个能够执行以下操作的类
class Test:
# code here
test = Test()
test["test"] = 1
test.test # returns 1
Run Code Online (Sandbox Code Playgroud)
dict在Python中使用魔术方法(例如不继承自)可能吗?
python attributes operator-overloading variable-assignment magic-methods
def __sub__()像这样对类型进行操作的魔术方法可以返回不同的结果类型吗?
例如,在下面的 User 类中,-1运算符返回一个字符串。要求是如果存在差异,则返回一个显示差异表示的字符串。
import copy
class User:
def __init__(self, username=""):
self.__user_name = username
def __sub__(self,other):
if other.__user_name != self.__user_name:
return "User name changed from {} to {}".format(self.__user_name,
other.__user_name);
else:
return ""
def set_user_name(self, username):
self.__user_name = username
user_1 = User("John")
user_2 = copy.copy(user_1)
user_2.set_user_name("Tom")
user_diff = user_1 - user_2
Run Code Online (Sandbox Code Playgroud)
之后,如果我们打印user_diff它将是“用户名从 John 更改为 Tom”。
是否允许这样做,并且是显示差异的方式之一,主要是与 相比,“-”返回不同的对象类型(字符串)User?
我有魔术方法的问题 __call
以下代码运行良好,除非在方法调用中有多个参数.我尝试了不同的解决方案,没有任何好的结果(只是$args或implode(', ' $args)不起作用)
public function __call($method, $args) {
if($this->methods[$method] != NULL)
return $this->objects[$this->methods[$method]]->$method($args[0]);
else trigger_error("Call undefined method " . $this->class . "::" . $method, E_USER_ERROR);
}
Run Code Online (Sandbox Code Playgroud)
如果我像这样写它也是有效的:
return $this->objects[$this->methods[$method]]->$method($args[0], $args[1], $args[3]);
Run Code Online (Sandbox Code Playgroud)
但正如您所看到的那样,这是不正确的,因为函数可以有0到无限的参数.
你知道如何修复多个参数的脚本吗?
我目前在PHP类示例中有以下__get/__ set方法:
class example{
/*Member variables*/
protected $a;
protected $b = array();
public function __get($name){
return $this->$name;
}
public function __set($name, $value){
$this->$name = $value;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,除了设置标准的受保护变量之外,我还希望能够在类中设置受保护的数组.我已经查看了一些其他问题,并找到了关于如何使用__get/__ set方法简单设置变量的一般建议,但没有任何允许使用这些魔术方法来设置BOTH数组和非数组的方法,即以下列方式:
$fun = new $example();
$fun->a = 'yay';
$fun->b['coolio'] = 'yay2';
Run Code Online (Sandbox Code Playgroud) 我有这个代码:
class Service {
public function get_session($token) {
foreach ($this->config->sessions as $session) {
if ($token == $session->token) {
$session->last_access = date('r');
return $session;
}
}
return null;
}
public function mysql_connect($token, $host, $username, $password, $db) {
if (!$this->valid_token($token)) {
throw new Exception("Access Denied: Invalid Token");
}
// will throw exception if invalid
$this->mysql_create_connection($host, $username, $password, $db);
$session = $this->get_session($token);
$id = uniqid('res_');
if (!isset($session->mysql)) {
$session->mysql = new stdClass();
}
$mysql = &$session->mysql;
$mysql->$id = array(
'host' => $host,
'user' …Run Code Online (Sandbox Code Playgroud) magic-methods ×10
php ×5
python ×5
oop ×2
python-3.x ×2
arrays ×1
attributes ×1
hex ×1
isinstance ×1
mapper ×1
metaclass ×1