zoukankan      html  css  js  c++  java
  • day23 01 类的命名空间

    day23  01 类的命名空间

    一、初识面向对象复习

    定义类:

    class

    函数:方法 动态属性

    变量:类属性 静态属性

    过程:

    (1)_init_方法:初始化:def _init_(self,参数)

      python帮我们创建了一个对象self

      每当我们调用类的时候就会自动触发这个方法

      在_init_方法里面可以对self进行赋值

    self是什么:self拥有属性都属于对象

      在类的内部,self就是一个对象

        比如:someone=person(),someone.walk==person.walk(someone),括号里面就是类里面的walk方法所传的参数self,

                   而且这个参数必须传

    (2)实例化:对象=类(参数是_init_方法的)

      实例==对象 没有区别

      对象查看属性:对象.属性

      对象调用方法:对象.方法名(参数)==类名.方法名(对象名,参数)

    (3)实例:

      求正方形的周长和面积:

    class square:
        def __init__(self,side_len):
            self.side_len_=side_len
        def perimeter(self):
            return self.side_len_*4
        def area(self):
            return  self.side_len_**2
    s=square(6)
    print(s.perimeter())
    print(s.area())

    运行结果:

    24
    36

    为什么计算这个周长和面积要使用类的调用和方法呢?

      正方形不同的地方就是边长不一样,不同的边长的正方形就归为一类

      有了固定的边长,当调用类里面的方法的时候就不需要再传参数了:print(s.perimeter()) , print(s.area())都不需要再传参数

    何为python入门,面向对象入门:

    python 入门:当你见到一个需求,你能翻译成python语言

    面向对象入门:当你见到一个需求,你能分析这个需求适不适合使用面向对象解决,如果适合,你能有一些想法

    二、类和对象的命名空间

    类里面可以定义两种属性:

      静态属性:

      动态属性:

    定义一个类:一种课程course,属性有:老师,课程名字,课程时间,课程费用

    class course:
        language='Chinese'
        def __init__(self,teacher,course_name,period,price):
            self.teacher=teacher
            self.course_name=course_name
            self.period=period
            self.price=price
        def func(self):
            pass
    python=course('李白','python','六个月','10000')
    print(python.teacher)
    print(python.course_name)
    print(python.period)
    print(python.price)
    course.language='English' #直接类名.静态属性是可以修改静态属性的
    print(course.language)
    course.__dict__['language']='English'  #但是使用类的字典形式去修改静态属性是不可能的,会报错
    print(course.language)
    print(python.language) #使用对象调用和查看类下的静态属性是可以的

    运行结果:

    Traceback (most recent call last):
    李白
      File "<encoding error>", line 31, in <module>
    python
    TypeError: 'mappingproxy' object does not support item assignment
    六个月
    10000
    Chinese
    English

    1、为什么对象可以直接调用查看类下的静态属性呢?

    print(python.language)---可以且不会报错

    类下的命名空间有:language, _init_, func
    对象self里面的命名空间有:teacher, course_name, period, price

    类对象指针(内存地址可以有对象的指向类的):可以根据对象属性找到对应的类,但是不能根据类找到对应的对象属性
    python.language:首先会在python里面找,如果找不到就会向对应的类中找,找到了就可以调用查看了
    course.name:是找不到的
    假设多加一门课程linux:
    python=course('李白','python','六个月','10000')
    linux=course('秋白','linux','六个月','10000')

    没有改变类下的静态属性language,然后打印

    print(python.language) 
    print(linux.language)

    是都可以打印出来的,且都是Chinese,而当通过

    course.language='English'

    修改静态属性之后,再次打印

    print(python.language)
    print(linux.language)

    结果也都会随之改变,都会变成English,当只通过对象修改类下的静态属性,在打印也是可以改的,如下:

    python.language='English'
    print(python.language)

    2、对于不可变数据类下的类下属性的操作

    上面的 python.language='English', print(python.language)的改法实际上是在python对象下创建了一个新的language=‘English’,所以再python里面可以找得到,就不会继续往类下面去找,在类下和linux下面(Linux指向的是类的命名空间)并没有创建新的language,类下的language是不可变的数据类下,所以当打印

    print(linux.language)
    print(course.language)

    的结果还是原来的language的结果,即Chinese所以:

    注意:对于不可变的数据类型来说,类变量最好使用类名操作

     3、对于可变的数据类型类下属性的操作

    比如前面的代码中类下的属性如果是: language=['Chinese'],然后按照下面进行修改打印:

    course.language[0]='English'
    print(course.language)
    print(linux.language)
    python.language[0]='English'
    print(python.language)
    print(course.language)
    print(linux.language)
    运行结果:
    ['English']
    ['English']
    ['English']
    ['English']
    ['English']

    此时通过对象名对类下的属性进行修改的时候就可以修改成功了,为什么呢?

    (1)对于course.language[0]='English'的修改

    类下的命名空间里面的language指向一个list的地址,而list的0元素指向的是Chinese的地址,当你通过 course.language[0]='English'

    去修改的时候,并没有改变language指向list,对象指向类的命名空间的过程,所以最后都可以通过对象找得到改变的类下的属性;

    (2)对于python.language[0]='English'的修改

    首先python对象先在自己的命名空间里面找一个可变的数据类型language,找不到就往类的命名空间里面找,因为对象指向类的命名空间,并且可以找到可变的数据类型language,所以在做python里面的修改的时候,类下的也会随之改变

    注意:对于可变数据类型来说,通过对象名修改类下属性是共享的,但是如果不是修改而是直接重新赋值的话是独立的(类似于前面的不可变数据类型通过对象名对类下属性是不能修改的)

     

    4、创建一个类,每实例化一个对象就记录下来,最终所有的对象都共享这个数据

    比较简单的代码:

    class Foo:
        count=0
        def __init__(self):
            Foo.count+=1 #使用类名操作类下属性,对象名调用类下属性的时候,类下属性会随着操作的变化而变化
    f1=Foo()
    f2=Foo()
    print(f1.count)
    print(f2.count)
    f3=Foo()
    print(f1.count) #实例化f3,然后通过对象f1操作类下属性,也是可以的,说明通过类名操作类下属性的结果是共享的

    运行结果:

    2
    2
    3

    这样就能满足每次实例化的时候count就会加一

    5、认识绑定方法

     一个类也是可以没有_init_方法的初始化的,只不过这样每次实例化的时候创建对象字典里面就没有任何值,是一个空的字典,代码如下:

    class Foo:
        def func(self):
            print('func')
    f1=Foo()

    运行结果:为空

    class Foo:
        def func(self):
            print('func')
    f1=Foo()
    print(Foo.func)
    print(f1.func)
    #这里的打印结果<bound method Foo.func of <__main__.Foo object at 0x0000016551112860>>会告诉我们一个绑定方法
    print(f1)

    什么叫做绑定方法呢?

    只有当对象去调用类下的方法的时候,调用方法的时候必须传入就是该对象,这样对象与方法之间就产生了一种绑定的关系,如果用类名调用就不会产生这种绑定关系

    先暂时了解一下,因为后面会讲到类外一种非绑定的方法

    6、包中的_init_

    为什么我们每次导入一个包就会自动调用执行里面的_init_文件?

    因为每次导入一个包 import package====类的实例化过程,包每次被导入就成为一个对象了,所以只要导入就可以使用里面的方法

    比如:

    import time

    time.time

  • 相关阅读:
    关于celery踩坑
    关于git的分批提交pull requests流程
    SymGAN—Exploiting Images for Video Recognition: Heterogeneous Feature Augmentation via Symmetric Adversarial Learning学习笔记
    AFN—Larger Norm More Transferable: An Adaptive Feature Norm Approach for Unsupervised Domain Adaptation学习笔记
    Learning to Transfer Examples for Partial Domain Adaptation学习笔记
    Partial Adversarial Domain Adaptation学习笔记
    Partial Transfer Learning with Selective Adversarial Networks学习笔记
    Importance Weighted Adversarial Nets for Partial Domain Adaptation学习笔记
    Exploiting Images for Video Recognition with Hierarchical Generative Adversarial Networks学习笔记
    improved open set domain adaptation with backpropagation 学习笔记
  • 原文地址:https://www.cnblogs.com/wxm422562/p/10864928.html
Copyright © 2011-2022 走看看