zoukankan      html  css  js  c++  java
  • Python 面向对象 中高级

    类成员:

    #字段 (也称为:属性) 静态字段 属于类 执行 既可以通过对象访问,也可以通过类访问
    普通字段 属于对象 执行只能通过对象访问 (即:定义在 __init__方法中的字段)
    class Foo:
        def __init__(self,name):
            # 字段
            self.name = name
        # 方法
        def show(self):
            print(self.name)
    obj = Foo('alex')
    print(obj.name) # 调用字段,后边不需要加括号
    obj.show()      # 调用方法,后边需要加括号

    字段实例:

    class Province:
        # 静态字段 (类比全局变量)
        country = '中国'
        def __init__(self,name):
            # 普通字段
            self.name = name
    henan = Province('河南')
    hebei = Province('河北')
    print(henan.name)       # 输出结果:河南  #通过对象访问
    print(Province.country) # 输出结果:中国  #通过类访问
    print(henan.country)    # 输出结果:中国  #通过对象访问

    #方法
     普通方法 保存在类中,需创建对象,由对象来调用      参数self 代指=>>调用对象
     静态方法   保存在类中,不需创建对象,由类直接调用,加@staticmethod装饰器,不需要传self参数
       类方法       保存在类中,由类直接调用,加@classmethod装饰器,需传递参数,约定俗成的self参数写法cls 代指=>> 当前类的类名

    对于静态方法中不需要传递self参数的情况,对比记忆必须传递self参数的,子类继承父类方法时的除了super方式外的第二种方式:fathor.func(self)

    # 静态方法

    class Foo:
        def bar(self):
            print('bar')
        @staticmethod
        def sta():
            print('123')
        @staticmethod
        def stat(a1,a2):
            print(a1,a2)
    Foo.sta()
    Foo.stat(1,2)
    # 输出结果:
    # 123
    # 1 2
     
    image

    # 类方法

    class Foo:
        def bar(self):
            print('bar')
        @classmethod
        def class_f(cls):
            print('我自己的类名')
    Foo.class_f()  # 通过类直接调用访问
    # 输出结果:我自己的类名
     

    # 普通方法,静态方法,类方法的应用场景:

    如果对象中需要保存一些值,在执行某功能时,
    需要使用对象中的这些值的情况下,使用===》普通方法
    
    不需要使用对象中的任何值的情况下,使用==》静态方法
    
    在方法里边如果需要用到当前类的话,使用==》类方法    
    
    # 这里注意下,类方法,其实作用不是很大,可以通过自己构造静态方法,传递参数(类名)来实现。
     

    # 特殊的方法类型 -- 属性 (俗称)

    加上@property装饰器,既有字段的特性,又有方法的影子!

    # 即:它采用方法的定义格式,字段的调用方式(也就是,调用的时候,不需要加括号。)

    class Foo:
        @property
        def pro(self):
            return 1
    obj = Foo()r = obj.proprint(r)
    # 输出结果:1

    # 如何利用@property修改设置pro方法的默认值

    class Foo:
        # 用于获取值    @property
        def pro(self):
            return 1    # 用于修改原先方法pro的默认值  下方@pro是方法名  除了支持@pro.setter写法外,还有@pro.delete     @pro.setter
        def pro(self,val):
            print(val)obj = Foo()r = obj.proprint(r)
    # 输出结果:1# 重新设置pro的值 obj.pro = 123# 注意:对于@pro.setter 和@pro.delete 其实这里并没有真正重新设置或者删除值,而是改变了对象调用的对应关系,相当于调用了新的方法!

    # 那么,属性有什么用呢?

    和它的特性一样,采用方法的定义格式,采用字段的调用方式;它没有什么特殊的用处,只是为了书写的时候,简略明了,省去括号。

    # 实例: 输入页码 显示分页 练习目的:通过利用属性 减少代码最后调用时,加括号。

    # -*- coding: utf-8 -*-
    class pagenation:
        def __init__(self,current_page):
            try:
                # 捕捉用户输入的错误格式 (非数字类型)
                p = int(current_page)
            except Exception as e:
                # 出现异常后 返回第1页
                p = 1   
            self.page = p
        
        @property
        def start(self):
            val = (self.page-1)*10
            return val
        
        @property
        def end(self):
            val = self.page * 10
            return val
    
    # 假如说相关数据有1000页        
    li = [] 
    for i in range(1000):   
        li.append(i)
        
    while True:
        p = input('请输入要查看的页码:') #每页显示10条
        # 1页 1,10
        # 2页 10,20
        # 3页 20,30
        obj = pagenation(p)
        # 因为类中采用了@property 所以下方调用start和end方法的时候,不需要加括号
        print(li[obj.start:obj.end])

    # 属性 property 的第二种写法 (即:不调用装饰器)

    # -*- coding: utf-8 -*-
    class Foo:
        def f1(self):
            return123
            
        def f2(self,v):
            print(v)
        
        def f3(self):
            print('del info myself define!')
        # 属性 除了@property装饰器写法的另一种写法 
        per = property(fget=f1,fset=f2,fdel=f3,doc='相关描述')
        # 注意:上方property() 括号中,算上doc,最多传递4个参数
        # 参数 fget,fset,fdel 分别对应下方的三种调用方式    
        
    obj = Foo()
    # 1 获取
    # ret = obj.per
    # print(ret)    
    
    # 2 设置
    # obj.per = 123456
    
    # 3 删除
    del obj.per

    # 注意:Python WEB框架 Django 的视图中 request.POST 就是使用的静态字段的方式创建的属性

    class WSGIRequest(http.HttpRequest):
        def __init__(self, environ):
            script_name = get_script_name(environ)
            path_info = get_path_info(environ)
            if not path_info:
                # Sometimes PATH_INFO exists, but is empty (e.g. accessing
                # the SCRIPT_NAME URL without a trailing slash). We really need to
                # operate as if they'd requested '/'. Not amazingly nice to force
                # the path like this, but should be harmless.
                path_info = '/'
            self.environ = environ
            self.path_info = path_info
            self.path = '%s/%s' % (script_name.rstrip('/'), path_info.lstrip('/'))
            self.META = environ
            self.META['PATH_INFO'] = path_info
            self.META['SCRIPT_NAME'] = script_name
            self.method = environ['REQUEST_METHOD'].upper()
            _, content_params = cgi.parse_header(environ.get('CONTENT_TYPE', ''))
            if 'charset' in content_params:
                try:
                    codecs.lookup(content_params['charset'])
                except LookupError:
                    pass
                else:
                    self.encoding = content_params['charset']
            self._post_parse_error = False
            try:
                content_length = int(environ.get('CONTENT_LENGTH'))
            except (ValueError, TypeError):
                content_length = 0
            self._stream = LimitedStream(self.environ['wsgi.input'], content_length)
            self._read_started = False
            self.resolver_match = None
    
        def _get_scheme(self):
            return self.environ.get('wsgi.url_scheme')
    
        def _get_request(self):
            warnings.warn('`request.REQUEST` is deprecated, use `request.GET` or '
                          '`request.POST` instead.', RemovedInDjango19Warning, 2)
            if not hasattr(self, '_request'):
                self._request = datastructures.MergeDict(self.POST, self.GET)
            return self._request
    
        @cached_property
        def GET(self):
            # The WSGI spec says 'QUERY_STRING' may be absent.
            raw_query_string = get_bytes_from_wsgi(self.environ, 'QUERY_STRING', '')
            return http.QueryDict(raw_query_string, encoding=self._encoding)
        
        # ############### 看这里看这里  ###############
        def _get_post(self):
            if not hasattr(self, '_post'):
                self._load_post_and_files()
            return self._post
    
        # ############### 看这里看这里  ###############
        def _set_post(self, post):
            self._post = post
    
        @cached_property
        def COOKIES(self):
            raw_cookie = get_str_from_wsgi(self.environ, 'HTTP_COOKIE', '')
            return http.parse_cookie(raw_cookie)
    
        def _get_files(self):
            if not hasattr(self, '_files'):
                self._load_post_and_files()
            return self._files
    
        # ############### 看这里看这里  ###############
        POST = property(_get_post, _set_post)
        
        FILES = property(_get_files)
        REQUEST = property(_get_request)

    所以,定义属性共有两种方式,分别是【装饰器】和【静态字段】,而【装饰器】方式针对经典类和新式类又有所不同。

    # python 成员修饰符

    公有成员

    私有成员

        __字段名 __方法名

       无法直接访问,可以通过在类内部自定义方法,间接访问。

      普通字段的私有属性

    image

    静态字段的私有属性

    image

    普通方法私有性

    image

    同理,静态方法同样有私有属性

    对于子类继承父类的情况,子类无法直接访问父类中的私有方法和字段,因为私有属性的私有性是相对于字段所属的类来讲的,也就是说,私有方法和私有字段只能通过所在的类内部访问调用。

    # 特殊成员

    类后边加()自动调用执行__init__ 方法

    对象后边加()自动调用执行__call__方法

    image
    加减乘除

    image

    析构方法

    只要对象在内存中,被垃圾回收机制找到销毁的时候,Python内部就会自动触发,执行析构方法。

    image

    __dict__ 通过字典的形式,将对象或者类的成员显示出来。

    image

    __getitem__ 实现通过索引取值

    __setitem__ 实现类似列表通过索引赋值的方法

    __delitem__ 实现类似列表通过索引删除相关值的方法

    上述方法 没有加逻辑之前,仅仅和下方对应的相关调用语句是一一对应关系,并没有真正的修改和删除。

    image

    单例模式

  • 相关阅读:
    代码审计中的XSS反射型漏洞
    PHP 代码审计代码执行注入
    4.代码审计之代码注入
    3.代码审计之 命令注入
    2.代码审计之超全局变量
    spring, spring mvc, mybatis整合文件配置详解
    StringUtils方法
    主键与外键
    MySQL面试题
    spring面试题
  • 原文地址:https://www.cnblogs.com/hellojesson/p/5897549.html
Copyright © 2011-2022 走看看