企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
[TOC] ## 1. 私有化 1. xx 公有变量 2. _xx私有属性或者方法,禁止导入,类对象和子类可以访问 3. __xx:双前置下划线,避免与子类中的属性名冲突,无法在外部直接访问(不能通过点的方式读取属性值,可写)(私有) 4. __xx__:双前后下划线,⽤户名字空间的魔法对象或属性。 例如: __init__ , __ 不要⾃⼰发明这样的名字 5. xx_:单后置下划线,⽤于避免与Python关键词的冲突 ~~~ #coding=utf-8 class Person(object): def __init__(self, name, age, taste): self.name = name self._age = age self.__taste = taste def showperson(self): print(self.name) print(self._age) print(self.__taste) def dowork(self): self._work() self.__away() def _work(self): print('my _work') def __away(self): print('my __away') class Student(Person): def construction(self, name, age, taste): self.name = name self._age = age self.__taste = taste def showstudent(self): print(self.name) print(self._age) print(self.__taste) @staticmethod def testbug(): _Bug.showbug() #模块内可以访问, 当from cur_module import *时, 不导⼊ class _Bug(object): @staticmethod def showbug(): print("showbug") s1 = Student('jack', 25, 'football') s1.showperson() print('*'*20) #⽆法访问__taste,导致报错 #s1.showstudent() s1.construction('rose', 30, 'basketball') s1.showperson() print('*'*20) s1.showstudent() print('*'*20) Student.testbug() ~~~ ![](https://box.kancloud.cn/50c1cb48351fa44654876e709060fb1d_1262x572.png) ## 2. property 对私有属性,方便的get和set ~~~ class Money(object): def __init__(self): self.__money = 0 def getMoney(self): return self.__money def setMoney(self, value): if isinstance(value, int): self.__money = value else: print("error:不是整型数字") ~~~ 我们先要获取money,就必须调用get和set了,特别不爽,还好有property属性 a.money 取值调用getter,a.money=100 表示设置值,调用setter 这样就是类似于属性那样赋值了,而且还可以实现属性或者方法的权限控制 * property ~~~ class Money(object): def __init__(self): self.__money = 0 def getMoney(self): return self.__money def setMoney(self, value): if isinstance(value, int): self.__money = value else: print("error:不是整型数字") money = property(getMoney, setMoney) ~~~ 这样就可以通过调用money ~~~ In [2]: a = Money() In [3]: a.money Out[3]: 0 In [4]: a.money = 100 In [5]: a.money Out[5]: 100 In [6]: a.getMoney() Out[6]: 100 ~~~ * 或者这么写property属性 ~~~ class Money(object): def __init__(self): self.__money = 0 @property # 定义了一个叫money的property属性 def money(self): return self.__money @money.setter # 解释为money属性的setter def money(self, value): if isinstance(value, int): self.__money = value else: print("error:不是整型数字") ~~~ a.money 取值调用getter,a.money=100 表示设置值,调用setter ~~~ In [3]: a = Money() In [4]: In [4]: In [4]: a.money Out[4]: 0 In [5]: a.money = 100 In [6]: a.money Out[6]: 100 ~~~ ## 3. 导入模块 1. 直接导入 import bao.xx.module 2. __import__ 例如 ~~~ module_plugin = __import__('plugins.user) # 导入包 module_file = getattr(module_plugin,user) # __import__获得模块包,通过getattr 才真正导入模块 ~~~ ## 4. for else 如果我们不是以除正常方式以外的其他任意方式退出循环,那么else分支将被执行。也就是在循环体内没有break语句、没有return语句,或者没有异常出现。 #### 4.1 for正常执行后,else执行 ~~~ >>> for i in range(5): ... print(i) ... else: ... print('Iterated over everything :)') ... 0 1 2 3 4 Iterated over everything :) ~~~ #### 4.2 有break发生,else不执行执行 ~~~ >>> for i in range(5): ... if i == 2: ... break ... print(i) ... else: ... print('Iterated over everything :)') ... 0 1 ~~~ 上面的代码中,我们在range(5)上迭代并打印每个数字。 1. 因为我们让循环正常完成,所以else分支也被执行,并打印出Iterated over everything :) 。 2. 相反,如果我们用break语句终止循环,那么else分支将不会执行: 3. 同样不要忘记,以上所有也适应while…else: ## 5. ` __init__.py` 作用详解 __init__.py 文件的作用是将文件夹变为一个Python模块,Python 中的每个模块的包中,都有__init__.py 文件。 1. 导入模块时,__init__.py文件中的代码会执行 2. 好处:在 __init__.py 里写一些程序内部用到的数据结构或为用户提供一个统一的接口。 ### 5.1 我们可以在__init__.py文件中批量导入我们所需要的模块,而不再需要一个一个的导入。 ~~~ # package # __init__.py import re import urllib import sys import os ~~~ ~~~ # a.py import package print(package.re, package.urllib, package.sys, package.os) ~~~ 注意这里访问__init__.py文件中的引用文件,需要加上包名。 `__init__.py`中还有一个重要的变量,__all__, 它用来将模块全部导入。 ~~~ # __init__.py __all__ = ['os', 'sys', 're', 'urllib'] # a.py from package import * 这时就会把注册在__init__.py文件中__all__列表中的模块和包导入到当前文件中来。 ~~~ #### 例 scrapy包的__init__.py文件 ~~~ __all__ = ['__version__', 'version_info', 'twisted_version', 'Spider', 'Request', 'FormRequest', 'Selector', 'Item', 'Field'] # Scrapy version import pkgutil __version__ = pkgutil.get_data(__package__, 'VERSION').decode('ascii').strip() version_info = tuple(int(v) if v.isdigit() else v for v in __version__.split('.')) del pkgutil # Check minimum required Python version import sys if sys.version_info < (2, 7): print("Scrapy %s requires Python 2.7" % __version__) sys.exit(1) # Ignore noisy twisted deprecation warnings import warnings warnings.filterwarnings('ignore', category=DeprecationWarning, module='twisted') del warnings # Apply monkey patches to fix issues in external libraries from . import _monkeypatches del _monkeypatches from twisted import version as _txv twisted_version = (_txv.major, _txv.minor, _txv.micro) # Declare top-level shortcuts from scrapy.spiders import Spider from scrapy.http import Request, FormRequest from scrapy.selector import Selector from scrapy.item import Item, Field del sys ~~~ scrapy包中导入了item包中的Item,此时可以这样:导入scrapy包后,直接使用Item ~~~ import scrapy class Yaoq(scrapy.Item): id = scrapy.Field() title = scrapy.Field() pubDate = scrapy.Field() author = scrapy.Field() authorLocation = scrapy.Field() content = scrapy.Field() ~~~ 如果 ~~~ from import * # 导入__all__中所有的模块 ~~~ #### 例一、 以 django forms 模块为例,在django.forms 模块里定义了各种各样的函数和类,这些函数和类分类放在不同的文件中。 ~~~ forms/ __init__.py extras/ ... fields.py forms.py widgets.py ... ~~~ 现在你要写一个新 form ,必须继承 Form 类,在 __init__.py 没发挥作用时的代码是这样的: ~~~ class CommentForm(forms.forms.Form): name = forms.fields.CharField() url = forms.fields.URLField() comment = forms.fields.CharField(widget=forms.widgets.Textarea) ~~~ 这样既不方便又很丑。而我们一般直接使用的是 django.forms 包下的 namespace。像这样: ~~~ from django import forms class CommentForm(forms.Form): name = forms.CharField() url = forms.URLField() comment = forms.CharField(widget=forms.Textarea) ~~~ 这就是在 forms/__init__.py 里写代码的好处(可以引入 widgets, forms, fields) ~~~ from django.forms.fields import * from django.forms.forms import * from django.forms.formsets import * from django.forms.models import * from django.forms.widgets import * ~~~ #### 例二、 有这样一个foo包 ~~~ foo/ __init__.py foofactories.py tallFoos.py shortfoos.py mediumfoos.py santaslittlehelperfoo.py superawsomefoo.py anotherfoo.py ~~~ 在init脚本里这样写: ~~~ __all__ = ['foofactories', 'tallFoos', 'shortfoos', 'medumfoos', 'santaslittlehelperfoo', 'superawsomefoo', 'anotherfoo'] # deprecated to keep older scripts who import this from breaking from foo.foofactories import fooFactory from foo.tallfoos import tallFoo from foo.shortfoos import shortFoo ~~~ 如此做,则可以在别的脚本里简单方便的写: ~~~ from foo import fooFactory, tallFoo, shortFoo ~~~ 简化了代码量。若 from foo import * ,则导入了init里的 __all__ 变量里注册的所有模块(不推荐) Django 经常把一些共通的类或函数放在 init 里,例如 django.conf.urls 包中的init里定义了三个方法 include,patterns,url。这些方法我们再熟悉不过。