python学习第七周之静态方法、类方法、属性方法和一些类的成员方法

1、静态方法:只是名义上归类来管理,实际上在静态方法访问不了类或实例中的任何属性。

(1)我们先看以下代码,实例化一个对象后,d可以直接调用talk()

class Dog(object):
    def __init__(self,name):
        self.name=name
    def talk(self):
        print("%s is talking" % self.name)
d=Dog("chen")
d.talk()

 (2)而我们在使用静态方法后,实例化后直接调用的话d.eat()会报错,因为在静态方法中,实例化的name是传递不进去eat函数中的;

class Dog(object):
    def __init__(self,name):
        self.name=name
    @staticmethod   #静态方法实际跟类没有关系,但是必须通过类名去调用;调用不了类的变量跟实例变量,相当于只是类的一个函数
    def eat(self):  #在实例化后是传不进来的,如果想要传进来,那么需要将d传进来
        print("%s is eating %s" %(self.name,'包子'))
d=Dog("chen")
d.eat()  #报错eat() missing 1 required positional argument: 'self',实例化后的self传不进去

 所以我们这时候如果要访问eat()方法,则需要将实例传递给改函数,即

d.eat(d)

 这样便可以将实例化对象d的name “chen”传递给eat函数。

2.类方法

类方法:只能访问类变量,不能访问实例变量。

如以下程序,我们将eat()方法定义为类方法,这时发现在实例化对象后,调用eat方法后报错,这时在构造函数中添加变量 self.n  = 333,执行仍然报错,说明类方法,不能访问实例变量

class Dog(object):
    def __init__(self,name):
        self.name=name
        self.n  = 333
    @classmethod     #类方法,只能访问类变量,不能访问实例变量
    def eat(self):  #在实例化后是传不进来的,如果想要传进来,那么需要将d传进来
        print("%s is eating %s" %(self.name,'包子'))
        print("%s is eat %s" %(self.n,'包子'))
d=Dog("chen")
d.eat()

 而我们在Dod类中添加两个类变量,这时再执行程序:

class Dog(object):
    n=333
    name="hhh"
    def __init__(self,name):
        pass

 由上可知,类方法只能访问类变量

3.属性方法

属性方法:把一个方法变成一个静态属性,

(1)如以下程序:

class Dog(object):
    def __init__(self,name):
        self.name=name 
    @property  #attribute
    def eat(self):
        print("%s is eating %s" %(self.name,'包子'))
d=Dog("chen")
#d.eat()  #这样调用时报错,应该d.eat
d.eat   # 属性方法:把一个方法变成一个静态属性

 此时,eat方法为静态属性,所以d.eat()调用时会报错,我们需要这样来调用:d.eat

(2)A 这时eat是一个属性,没有办法通过括号来传递参数,这时如果要给eat传递参数,要写一个相同的eat函数,这时传递参数时便可以传递进来;

  @eat.setter
    def eat(self, food):
        print("set to food:", food)
d=Dog("chen")
d.eat   # 属性方法:把一个方法变成一个静态属性
d.eat="baozi"   #如果要传递参数,必须在写一个相同的函数,@eat.setter

 以上程序输出结果如下: 这时看到baozi被传递进来

chen is eating 包子
set to food: baozi    

   B 将以上给eat的赋值存储下来,在打印的时候发现输出结果发生变化:

class Dog(object):
    def __init__(self,name):
        self.name=name
        self.__food=None
    @property  #attribute
    def eat(self):
        print("%s is eating %s" % (self.name, self.__food))
    @eat.setter
    def eat(self, food):
        print("set to food:", food)
        self.__food=food
d=Dog("chen")
d.eat   # 属性方法:把一个方法变成一个静态属性
d.eat="baozi"   #如果要传递参数,必须在写一个相同的函数,@eat.setter
d.eat

 将传递给eat的参数“baozi”存下来:结果如下

chen is eating None
set to food: baozi
chen is eating baozi

 (3)删除属性:再写一个相同的函数,删除;这时在调用d.eat报错

@eat.deleter
    def eat(self):
        del self.__food
        print("删除完成")
del d.eat 
d.eat #删除私有属性后,再次调用时报错

 4.类的特殊成员方法:(以3的程序为例)

(1)__call__() 方法

  __call__对象后面加括号,触发执行。

构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

将d实例化d=Dog("chen")后,再直接d()报错,这时我们在类Dog中写一个__call__()方法,

class Dog(object):

        def __call__(self, *args, **kwargs):
        print("running call",args,kwargs)
d=Dog("chen")
d()     #d=Dog("chen") d(),与Dog("chen")()一样
d(1,2,3,name=333)

 这时看到输出结果为:

running call () {}
running call (1, 2, 3) {'name': 333}

 (2)__dict__()方法

  没有实例化对象时,将类的方法以字典的形式打印出来,但是不包括实例的属性

#__dict__方法
print(Dog.__dict__)   #没有实例化对象以字典的形式将类的方法打印出来,不包括实例属性

   实例化对象后,打印对象的实例属性:

d=Dog("chen")
print(d.__dict__)    #通过实例调用,只打印了所有的实例变量
输出结果如下:
{'name': 'chen', '_Dog__food': None}

(3)__str__方法:

  如果我们直接实例化后打印,没有写str方法的话,输出的为内存地址

d=Dog("chen")
print(d)  #如果没有str方法,打印输出为<__main__.Dog object at 0x01104B70>;如果写入str方法,在打印对象时,默认输出该方法的返回值

   如果我们在类Dog中写入str方法,在实例化后打印,输出结果为该方法的返回值

    def __str__(self):
        return "<obj:%s>"%self.name
d=Dog("chen")
print(d)  #如果写入str方法,在打印对象时,默认输出该方法的返回值:<obj:chen>

猜你喜欢

转载自www.cnblogs.com/wuxiaoru/p/11504768.html