欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Define class in Python

程序员文章站 2022-05-29 09:28:27
...

1. 面向对象

面向对象是一种思考角度, 做法: 将万物抽象成类.

2. class

class是抽象的概念, 是万事万物的abstract, 是一类事物共同特征的集合, 就是attribute和method的集合. object
是class的具象化, 是一个instance.

如有一个class是人类, 人类这个类可以创造出一个个instance, 也就是一个个人:
人名 = 人类(属性)

身高体重肺活量是这个人的attribute:
人名.身高
人名.体重

吃饭睡觉papapa是这个人的method:
人名.睡觉()
人名.吃饭(食物)
#这里的食物是另一种class的instance, 这个类就是都是能吃的东西, 也就是说一个class的instance可以和另一个class的instance相互作用
#同种类之间的实例, 也可以相互作用, 比如: dict1.update(dict2)

attribute, 是对对象状态的抽象, 用数据结构来描述.
method, 是对对象行为的抽象, 用操作名和实现该操作的方法来描述.

对象是数据和操作的封装.

3. 封装, 继承和多态

python 不存在多态.
Define class in Python

一张图自己意会一下吧.

4. class of Python

4.1 define

class ClassName:
    name = 'NAME'
    def foo(self):
        print(self)

这样就define了一个class, 把这个class和define时用的ClassName绑定起来.

‘name’ is attribute of this class, foo是class的method, but we only can call it through an instance of this class.

4.2 make instance

a = ClassName() 
#attention, creat an instance needs call this class

Creat an instance equal to call .__init__(self, ….), it is exists in every class define procession and can make an instance of its params as instance’s attributes.

__init__ also has no return.

__init__ ‘s first param must be self.

method和function的区别, 本质区别就是一个是在类的内部定义, 一个不是.

__new__(cls, *args, **kwargs) 方法:
这个是实例化的类方法, python设定好的

4.3 class variable and instance variable

class Person:
    age = 3 #这个就是类变量(就是类的属性)
    def __init__(self, name):
        self.name = name  #这个就是实例变量(就是实例的属性)

4.4 class attribute and instance attribute

特殊属性:
.__name__ : 对象名, 类对象有名字, 但是实例对象没有自己的名字.
.__class__ : 对象的类, 实例对象有自己的类, 相当于type(object), 都返回类.
.__dict__ : 对象属性的字典, 类的字典要和实例的字典区分开来
.__qualname__ : 点示法显示函数名称、所在的类、模块等梯级地址
.__module__ : 看这个对象是哪个模块下的, 主模块是’main
.__wekref__ : ????
.__globals__ : 对类的方法使用, 返回一个字典, 里面是全局下定义的所有的变量.

4.5 The Squence of Searching Instance Attribute

用实例来访问属性, 访问的字典是(但是实际操作不一定是这样的, 就这样理解):
实例.__dict__ = 类.__dict__.update(实例.__dict__)

访问类的属性, 并进行修改, 只是修改了类的属性的__dict__, 实例的属性没有改变. 但是用实例调用类的这个改变过得类的属性, 根据上面的规律, 得到的值当然是修改过的.

通过实例来访问类属性, 并进行修改是不会修改类的属性的, 但是这个被修改过得实例属性会保存下来, 记在实例的__dict__里.

总结就是, 只有修改了实例的属性值(实例属性或者类属性), 实例的__dict__就会相应的更新value或者增添key-value pair.

4.6 Decorator of class

例:

class ClassName:
    def function1():
        block
    def function2(self):
        block

function1的参数里不写self, 意味着这个函数必须通过类来访问, 通过实例无法访问

类调用function1, 不需要传参, Person.function1(), 就是简单的函数调用

类调用function2, 需要传参, 两种调用方式, Person.function2(Person()) 和 Person().function2(), 前者是给self传了一个参数Person(), 后者是把前面的对象Person(), 当做实参传给self

def addfuck(cls):
    cls.fuck = 'fuck'
    return cls

@addfuck  # T = addfuck(T)
class T:
    name = 'T'
    def __init__(self, t):
        self.t = t

a = T('t')

a.__dict__ # {'t': 't'}
T.__dict__
# mappingproxy({'__module__': '__main__',
          'name': 'T',
          '__init__': <function __main__.T.__init__(self, t)>,
          '__dict__': <attribute '__dict__' of 'T' objects>,
          '__weakref__': <attribute '__weakref__' of 'T' objects>,
          '__doc__': None,
          'fuck': 'fuck'})

总结@classmethod和@staticmethod是改变传参方式的,
前者: 如果用实例来调用, 第一个参数传入这个实例的类; 用类来调用, 第一个参数直接传入这个类
后者: 无论用实例还是用类来调用, 都不会把调用者当成第一参数传入(就是删除了第一个隐式传入的第一个参数)

如果这两个装饰器都不加, 用实例来调用, 就把实例当成第一参数传入, 用类来调用, 必须手动在()中传入实例.

属性装饰器:
@property 获取装饰器getter, 可以把私有属性, 按平常的形式访问, 把属性变成只读

@x.setter 修改装饰器, 可以按平常形式修改私有属性, 但是前面必须有getter就是必须有@property

@x.deleter 删除装饰器, 可以把私有属性删除

4.7 private attribute and protected attribute

在__init__() 中定义的实例属性, self.__属性名, 就会把这个属性变成私有属性
例:

class Test:
    def __init__(self, a, b):
        self.a = a
        self.b = b
        self.__c = 100

    def getc(c)
        return self.__c

__c就是私有属性, 直接用.c修改, 不好使, 因为内部自动给这个c改名了, 改成了_Test__c, 用这个名一样也能改.

4.8 other

__del__是在类定义时候放在里面的, 表示在这个类的实例消亡的时候, 把实例内部调用的资源都关闭了

相关标签: class