PHP面向对象深入理解之三(类中的魔术方法)

通常情况下,不建议使用魔术方法,因为会增加opcode,影响程序的性能。

1. __toString


通常你使用print 打印一个类的时候,你会发现打印出来的类似于 Object id#1
的id句柄,如果我们不想得到这样的句柄,那我们可以改写__toString 方法



class A
{
	private $name = 'A class';
	public function __construct($name)
	{
	    $this->name = $name;
	}
	public function __toString()
	{
	    return $this->name;
	}
}
$a = new A('a');
$b = new A('b');
print $a;
print $b;



2. __set 和__get

__get方法是某个成员变量不能存在的时候,访问会报错,可以通过设置__get,避免报错,通常与__set配合使用
__set则是无此变量时,可以设置默认加入方式,让__get能访问到



class A
{
    private $data = null;
	public function __get($name)
	{
        return isset($this->data[$name])?$this->data[$name]:'';
	}
	public function __set($name,$value)
	{
	    $this->data[$name] = $value;
	}
}
$a = new A();
$a->age = 13;
print $a->age;





3. __sleep 和 __wakeup

__sleep 用于对象serialize序列化的时候,准备序列化需要的资源
  它必须返回的是当前类的成员变量的名字组成的数组
__wakeup 则相反,在对象unserilize反序列化的时候 会优先执行的操作



class A 
{
    public $name = 'zhansan';
	public function __sleep()
	{
	    return array('name');
	}
	public function __wakeup()
	{
	    echo 'bbb';
	}
	public function geta()
	{
	    echo 'a is running ';
	}
}

$a = new A();
$astr = serialize($a); //注意一个对象被序列化的时候 他的方法和功能依然被保留
print $astr;           //只是暴露给外界的很少
$newa = unserialize($a); //反序列化的时候 就被重新激活了会优先调用__wakeup
$newa->geta(); //不信,你看 仍然能调用




打印结果:O:1:"A":1:{s:4:"name";s:7:"zhansan";}bbba is running


4.__invoke

当尝试以调用函数的方式,调用一个对象的时候,__invoke就被激活了


class A
{
	public function __invoke($argvs)
	{
	    var_dump($argvs);
	}
}
$a = new A();
$a('obj is called');




打印: string(13) "obj is called"


5.  __call 和 __callStatic(5.3.0以后)

当对象调用一个不存在的方法时,会自动触发__call方法
而调用一个不存在的静态方法时,会自动触发__callStatic



<?php
class A
{
        public function __call($funcname,$argvs)
        {
            echo 'call:';
            var_dump($funcname,$argvs);
        }
        public static function __callStatic($funcname,$argvs)
        {
            echo 'call static:';
            var_dump($funcname,$argvs);
        }
}
$a = new A();
A::runaaa('abc');
$a->getbbb('111');


打印结果:
call static:string(6) "runaaa"
array(1) {
  [0]=>
  string(3) "abc"
}
call:string(6) "getbbb"
array(1) {
  [0]=>
  string(3) "111"
}

6. __isset 和 __unset

对象的不存在属性或不可访问属性调用 isset()和empty() 方法 __isset 会被触发
unset() 则触发 __unset


class A
{
    private $data = array();
    public function __get($name)
    {
        return $this->data[$name];
    }
    public function __set($name,$value)
    {
        $this->data[$name] = $value ;
    }
	public function __isset($name)
	{
	    echo 'isset:';
        return isset($this->data[$name]);
	}
	public function __unset($name)
	{
	    echo 'unset:'
	    unset($this->data[$name]);
	}
}
$a = new A();
$a->name='aa';
var_dump(isset($a->name));
unset($a->name);
var_dump(isset($a->name));


打印结果:
isset:bool(true)
unset:isset:bool(false)


7. __clone

当调用clone 操作符来复制一个新对象时,会触发__clone 方法
如果,对象的某些属性是使用的引用的方式,新对象仍然会因为旧对象的改变而改变;



class A
{
	public $name = 'lisi';
	public $obj = null;
	public function __clone()
	{
	    echo 'clone is called';
	    $this->name = 'lisi'; //这里做一些初始化操作
	    $this->obj = clone $this->obj; //做深度拷贝
	}
}
$a = new A();
$a->name = 'zhao';
$b = clone $a;
var_dump($b->name);
var_dump($a->name);
$c= new A();
$a->obj = $c;




打印:
clone is calledstring(4) "lisi"

string(4) "zhao"






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 魔术方法是Python中的特殊方法,它们以双下划线开头和结尾,例如__init__、__str__、__add__等。这些方法可以在的实例化、运算符重载、属性访问等方面提供特殊的行为。 __init__方法是一个特殊的构造函数,用于初始化的实例。__str__方法用于返回对象的字符串表示形式,可以通过print函数输出。__add__方法用于重载加法运算符,可以实现自定义的加法操作。其他常用的魔术方法还包括__eq__、__lt__、__gt__等,用于比较运算符的重载。 学习魔术方法可以让我们更好地理解Python面向对象编程的特性,提高代码的可读性和可维护性。 ### 回答2: 魔术方法是Python中最有趣且也是最强大的概念之一。魔术方法(也称为特殊方法或双下划线方法)是一些特殊的方法,它们以双下划线(__)开头和结尾,并具有特定的名称。 这些特殊方法可以为我们提供许多有用的功能,例如重载操作符,处理的属性,实现自定义迭代器,使用描述符等。 下面是一些常见的魔术方法: __init__:这是最常见的魔术方法。当创建一个实例时,它会被自动调用。它用于初始化对象的属性。 __str__:当你想要将一个对象转换成字符串时,这个方法会被调用。如果你不指定__str__方法,Python默认会使用对象的名和内存地址来表示对象。 __repr__:这个方法和__str__方法似,也是用于将对象转换成字符串。但是__repr__方法在调试时有很大的作用,因为它返回的字符串可以用来唯一地标识对象。 __len__:这个方法可以返回对象的长度。例如,如果你想获取一个字符串的长度,你可以使用len("hello"),在底层,它实际上是调用了字符串对象的__len__方法。 __getattr__和__setattr__:这些方法允许你动态地获取和设置对象的属性。当你访问一个不存在的属性时,__getattr__方法会被调用。当你设置一个属性时,__setattr__方法会被调用。 __call__:这个方法允许你将对象作为函数调用。当你调用一个对象时,Python实际上是在调用对象的__call__方法。 除了上面列举的方法,还有许多其他的魔术方法,例如__cmp__,__hash__,__iter__等等。学习这些魔术方法将使你能够更好地理解Python的面向对象编程模型。 总之,学习和理解魔术方法是Python面向对象编程中的一个关键概念,因为它们可以帮助你实现更加灵活和强大的代码。如果你想成为一名Python高手,那么深入学习魔术方法是不可避免的。 ### 回答3: Python中的“魔术方法”指的是每个类中定义的特殊方法,它们以双下划线(__)开头和结尾,并且有着特定的用途。通过使用这些魔法方法,我们可以自定义的行为,并为程序提供更高级别的功能。 以下是Python中常用的一些魔术方法: 1. __init__:这是最常用的魔术方法之一,它用于初始化一个的对象,以及定义的属性和方法。 2. __str__:此方法用于返回对象的字符串表示形式,似于Java中的toString()方法。 3. __repr__:与__str__似,但是返回的是对象的“官方”字符串表示形式,通常用于调试和开发。 4. __getattr__:当试图访问一个不存在的属性时,此方法被调用。 5. __setattr__:当尝试设置的属性时,此方法被调用。 6. __delattr__:当尝试删除的属性时,此方法被调用。 7. __call__:将对象作为函数调用时,此方法被调用。 8. __len__:返回对象的长度。 9. __getitem__:允许通过索引访问对象的元素。 10. __setitem__:允许通过索引设置对象的元素。 11. __delitem__:允许通过索引删除对象的元素。 通过了解和使用这些魔术方法,我们可以编写出更高效、更灵活、更具可读性的Python代码,并且实现似于内置型一样的功能。例如,我们可以实现一个自定义列表,似于Python的list型,然后使用上述魔术方法来访问、设置和删除元素。同时,我们还可以自定义变量和函数的行为,使我们的Python代码变得更具有表现力和弹性。 总之,了解和掌握Python的魔术方法是Python编程中必不可少的一部分,对于理解和编写实际应用程序非常有价值。在实践中,我们可以根据实际情况选择恰当的魔术方法,从而创建更灵活、更高效的Python

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值