美文网首页PYTHON进阶
2.类的方法介绍

2.类的方法介绍

作者: Stone_説 | 来源:发表于2020-12-30 01:19 被阅读0次

目录:
1.装饰一个类
2.类方法和静态方法

1.装饰一个类

为一个类增加一些属性:

>>> def add_name(name,cls):
...     cls.NAME = name
>>> def add_name(name):
...     def wrapper(cls):
...             cls.NAME = name
...             return cls
...     return wrapper
>>> @add_name('Tom')
... class Person:
...     AGE = 3
>>> print(Person.NAME)
Tom

本质上是为类对象动态的添加一个属性,而Person这个标识符指向这个类对象

2.类方法和静态方法

前面的例子中定义的__init__等方法,这些方法本身都是类的属性,第一个参数必须是self,而self必须指向一个对象,也就是类实例化之后,由实例来调用这些方法。

2.1普通函数
>>> class Person:
...     def normal_method():
...             print('normal')
>>> Person.normal_method()
normal
>>> Person().normal_method()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: normal_method() takes 0 positional arguments but 1 was given

>>> print(Person.__dict__)
{
'__module__': '__main__', 
'normal_method': <function Person.normal_method at 0x7fc6612e3820>, 
'__dict__': <attribute '__dict__' of 'Person' objects>, 
'__weakref__': <attribute '__weakref__' of 'Person' objects>, 
'__doc__': None
}
Person.normal_method()可以放在类中定义,因为这个方法只是被Person这个名词空间管理的方法,normal_method是Person的一个属性而已。
由于normal_method在定义的时候没有指定self,所以不能完成实例对象的绑定,不能用Person().normal_method()调用。
虽然语法正确,禁止使用。
2.2类方法
>>> class Person:
...     @classmethod
...     def class_method(cls):
...             print('class = {0.__name__} ({0})'.format(cls))
...             cls.HEIGHT = 170
>>> Person.class_method()
class = Person (<class '__main__.Person'>)
>>> Person().class_method()
class = Person (<class '__main__.Person'>)

>>> print(Person.__dict__)
{
'__module__': '__main__', 
'class_method': <classmethod object at 0x7fe9b1134430>, 
'__dict__': <attribute '__dict__' of 'Person' objects>, 
'__weakref__': <attribute '__weakref__' of 'Person' objects>, 
'__doc__': None, 
'HEIGHT': 170
}

NOTE:
1.在类定义中,使用@calssmethod装饰器修饰的方法
2.必须至少有一个参数,且第一个参数留给了cls,cls指代调用者即类对象自身
3.cls这个标识可以是任意合法名称,但是为了易读,请不要修改
4.通过cls可以直接操作类的属性,但是cls无法直接操作类

2.3静态方法
>>> class Person:
...     @classmethod
...     def class_method(cls):
...             print('class = {0.__name__} ({0})'.format(cls))
...             cls.HEIGHT = 170
...     @staticmethod
...     def staticmethod():
...             print(Person.HEIGHT)
>>> Person.class_method()
class = Person (<class '__main__.Person'>)
>>> Person.staticmethod()
170
>>> print(Person.__dict__)
{
'__module__': '__main__', 
'class_method': <classmethod object at 0x7f007fd74430>, 
'staticmethod': <staticmethod object at 0x7f007fd746d0>, 
'__dict__': <attribute '__dict__' of 'Person' objects>, 
'__weakref__': <attribute '__weakref__' of 'Person' objects>, 
'__doc__': None, 
'HEIGHT': 170
}

NOTE:
1.在类定义中,使用@staticmethod装饰器修饰的方法
2.调用时,不会隐式的传入参数
3.静态方法,只是表明这个方法属于这个名词空间,函数归在一起,方便组织管理

2.4方法的调用
>>> class Person:
...     def method(self):
...             print("{}'s method".format(self))
...     @classmethod
...     def class_method(cls):
...             print('class = {0.__name__} ({0})'.format(cls))
...             cls.HEIGHT = 170
...     @staticmethod
...     def static_method():
...             print(Person.HEIGHT)

>>> print(2,Person.class_method())
2 class = Person (<class '__main__.Person'>)
>>> print(3,Person.static_method())
3 170

>>> print(4,tom.method())
4 <__main__.Person object at 0x7f7c666dd130>'s method
>>> print(5,tom.class_method())
5 class = Person (<class '__main__.Person'>)
>>> print(6,tom.static_method())
6 170

NOTE:
1.类几乎可以调用所有内部定义的方法,但是调用普通的方法时会报错,原因是第一参数必须是类的实例
2.实例也几乎可以调用所有的方法,普通的函数调用一般不可能出现,因为不允许这样定义
3.类除了普通方法都可以调用,普通方法需要对象的实例作为第一参数
4.实例可以调用所有类中的方法(包括类方法,静态方法),普通方法传入实例自身,静态方法和类方法需要找到实例的类。

2.5 补充
>>> class Person:
...     def method(self):
...             print("{}'s method".format(self))
>>> tom = Person()
>>> tom.method()
<__main__.Person object at 0x7f7fd2710430>'s method
>>> Person.method()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: method() missing 1 required positional argument: 'self'
>>> Person.method(tom)
<__main__.Person object at 0x7f7fd2710430>'s method
>>> tom.__class__.method(tom)
<__main__.Person object at 0x7f7fd2710430>'s method

NOTE:
1.tom.method()调用时候,会绑定实例,调用method方法时,实例tom会注入到method中
2.Person.method(),使用类调用,不会有实例绑定,调用method方法时,缺少第一参数

相关文章

网友评论

    本文标题:2.类的方法介绍

    本文链接:https://www.haomeiwen.com/subject/cekcoktx.html