对象中的PHP和Python静态方法,两个不同的世界......?

时间:2010-11-30 13:47:19

标签: php python

我是php编码器,试图进入python世界,对我来说这很难。

php中最大的静态方法是实例的自动构建器。无需在每个文件中(或使用不同的构造函数参数,在一行中)声明对象(如果需要一次)

<?php
class Foo { 
    function __constructor__(){
        $this->var = 'blah';
    }
   public static function aStaticMethod() {
       return $this->var;
   }
}

echo Foo::aStaticMethod();
?>
我们可以从静态方法调用构造函数不是吗?我们可以访问类中的所有内容,因为它是简单的方法...我们甚至可以在php类中使用STATIC CONSTRUCTOR并像这样调用它:Object :: construct() - &gt; myMethod(); (每次传递不同的参数)

但不是在python ???? @staticmethod使类中的方法成为一个看不到任何东西的简单函数?

class socket(object):

def __init__(self):
    self.oclass = otherclass()
    print 'test' # does this constructor called at all when calling static method??                

@staticmethod
def ping():
    return self.oclass.send('PING') # i can't access anything!!!


print Anidb.ping()

我无法从那个该死的静态方法访问任何东西,它就像一个独立的函数或类似的东西.. ??

也许我正在使用错误的装饰器?也许在python中有类似php提供的静态方法?

1)请说明为什么静态方法是孤立的 2)请告诉我如何制作像php静态方法一样的行为。 3)请告诉我替代实际用法,如果php静态方法行为是坏事

P.S。所有这一切的目标是尽可能少地编写代码。 P.p.s赞赏示例代码的重评论

谢谢。

3 个答案:

答案 0 :(得分:3)

您想要classmethod。这提供了类作为第一个参数。

修改

class C(object):
  foo = 42

  @classmethod
  def printfoo(cls):
    print cls.foo

C.printfoo()

答案 1 :(得分:3)

PHP中的静态方法并不像您所认为的那样,它们无法访问实例成员。没有$this!和他们一起。

<?php
class Foo {

    public static $var = 'foo ';

    function __construct(){
        echo 'constructing ';
        $this->var = 'blah ';
    }

    public function aMethod() {
        return $this->var;
    }
    public static function aStaticMethod() {
        #return $this->$var;  -> you can't do that,
        # $this can be accessed only in instance methods, not static
        return self::$var;
    }
}

$foo = new Foo();
echo $foo->aMethod();

echo Foo::aStaticMethod();

?>

Python在对象中有三种方法static方法就像函数定义的ouside类,将它们放在对象中的唯一用途就是将它们作为辅助函数保存在类中。 class方法只能访问类中定义的变量(装饰器@classmethod)。这或多或少是PHP调用静态成员或方法。这些方法的第一个参数应该是cls,并且可以通过cls访问类的内容。普通方法必须以self作为第一个参数,并且是唯一能够访问实例成员的方法。

如果你想要几个相同类型的对象,你肯定需要实例,而其他类型不是你想要的。如果您只有一个对象实例,则可以使用类方法(或PHP静态方法)。

但在大多数情况下,如果您不知道原因并且只是坚持使用对象和常规方法的实例,那么您不应该这样做,否则就会过早优化,而您的代码可能会因为许多限制而在以后咬你你介绍一下。

答案 2 :(得分:2)

我看到你已经接受了另一个答案,但我不确定它是否适用于你的代码。具体来说,oclass变量仅为类的实例创建,而不是为类本身创建。你可以这样做:

class socket(object):
    oclass = otherclass()                

    @classmethod
    def ping(cls):
        return cls.oclass.send('PING')

socket.ping()

但是,使用现有代码并删除所有装饰器,您可以简单地实例化它并在同一行上使用方法:

socket().ping()