类变量、绑定方法、静态方法和类方法

类变量

面向对象的结构

  • 类成员
    • 类变量(静态字段/属性)
    • 方法
      • 绑定方法:常规的形式(只能通过对象调用)
      • 静态方法(推荐类调用)
      • 类方法(推荐类调用)
      • 属性
        对象可以调用所用的方法
  • 实例(对象)
    • 实例变量(字段/属性)
class Foo:
    city = "北京" #成员city就叫类变量
    def __init__(self,name):
        self.name = name

    def func(self):
        pass

obj1 = Foo("杨子莲")
obj2 = Foo("女神")
print(obj1.city)
print(Foo.city)#比较正式的写法
print(obj.city)

'''
输出结果为:
北京
北京
北京
'''
  • 定义时:写在类的下一级和方法同级

  • 访问:

    • 类.类变量名称
      对象.类变量名称
      

示例一

class Base:
    x = 1
obj = Base()
print(obj.x)
'''
类里面没有方法只有一个类变量,所以输出的结果为1
'''
obj.y = 123 #在对象中添加一个y = 123的变量
obj.x = 123 #在对象中添加一个x-123的变量,并不能改变类中的x = 1的
Base.x = 666 #改变了类中的x = 1的变量

示例二

#练习1
class Base:
    x = 1

class Foo(Base):
    pass

print(Foo.x) #继承关系
#结果为1

#练习2
class Base:
    x = 1
class Foo(Base):
    pass
Foo.x = 666 #只改变自己,并没有改变Base
print(Base.x)
print(Foo.x)
'''
结果为
1
666
'''

示例三

class Parent:
   x = 1
class Child(Parent):
   pass
obj = Child()
print(obj.x)
obj.x = 2 #只改变了对象而未改变类,所以Child.x的结果依然为1
print(Child.x)
'''
输出结果为:
1
1
证明:
不用非得实例化后才能执行类,在不执行的时候依然可以调用其中的数据
'''

总结:

  • 找变量优先找自己 ,自己没有找 类 或 基类
  • 修改时或赋值时只能在自己的内存中进行赋值,不能修改父级或其他

绑定方法

class Foo:
def init(self):
self.name = 123

def func(self,a,b):
    print(self.name,a,b)

obj = Foo()
obj.func(1,2)

静态方法

  • 定义:

    • @staticmethod装饰器
    • 参数无限制
  • 执行:

    • 类.静态方法
    class Foo:
        def __init__(self):
            self.name = 123
    
        def func(self,a,b):
            print(self.name,a,b)
    
        def func1(a,b):
            print("yang")
    
        @staticmethod
        def f1(a,b): #静态方法:不用创建对象,直接通过类进行调用
            print(123)
    
    Foo.func1("1","zi")
    
    '''
    思考:
    我认为通过静态方法调用的函数和普通定义一个函数的区别不大。就像func1与f1的差别并不是很大一样。
    

在没有数据封装进去的时候,用静态方法。它就在那嘛,静静的不用绑定数据所以叫静态方法
'''

## 类方法

```python
class Foo:
  @staticmethod
  def f1(a,b): #静态方法:不用创建对象,直接通过类进行调用
      print(123)

  @classmethod #类方法
  def f2(cls,a,b):#cls为固定参数,返回的为当前类
      print("cls是当前类",cls)
      print(a,b)
      '''
      结果为:
      cls是当前类 <class '__main__.Foo'>
  	1 zi
      '''

Foo.f2("1","zi")

类方法

  • 定义:
    • @classmethod装饰器
    • 至少有cls参数,当前类
  • 执行:
    • 类.类方法
    • 对象.类方法(不推荐)

问题 @classmethod和staticmethod的区别

  • 一个是类方法一个是静态方法。
  • 定义:
    • 类方法:用@classmethod做装饰器且至少有一个cls参数
    • 静态方法:用staticmethod做装饰器且参数无限制
  • 调用:
    • 类.方法直接调用
    • 对象.方法也可以调用

麦叔:静态方法、类方法、静态方法

class Dog(object):
    dogbook = {"黄色":30,"黑色":20,"白色":0}
    def __init__(self,name,color,weight):
        self.name = name
        self.color = color
        self.weight = weight

    def bark(self):
        print(f"{self.name}叫了起来")

    @classmethod #类方法主要是用来方位类属性
    def dog_num(cls): #就直接访问类的属性
        num = 0
        for v in cls.dogbook.values(): #就访问类的属性
            num = num + v
        return  num

    @staticmethod #与谁都无关,强行封装
    def total_weight(dog):
        total = 0
        for o in dog:
            total = total + o.weight
        return total

print(f"共有{Dog.dog_num}条狗")
d1 = Dog("大黄","黄色",10)
d1.bark()
print(f"共有{d1.dog_num()}条狗")
d2 = Dog("旺财","黑色",8)
d2.bark()
print(f"狗共重{Dog.total_weight([d1,d2])}公斤")


#实例化方法就是正常的方法
#示例化方法是为了访问类的属性
#静态方法就是啥也不管强行归类,为了保持
posted @ 2020-09-27 11:26  小杨的冥想课  阅读(209)  评论(0编辑  收藏  举报