python 中文官方文档:https://yiyibooks.cn/xx/python_352/index.html
类和元类
类由元类创建
type 是一个元类 type('class_name',(par_vlass_name),{})
字典不可以是函数
博客地址:http://blog.jobbole.com/21351/
创建一个类的过程:
当做了
class Foo(Bar):
pass
Foo中有__metaclass__这个属性吗?如果是,Python会在内存中通过__metaclass__创建一个名字为Foo的类对象(类对象)
如果Python没有找到__metaclass__,它会继续在Bar(父类)中寻找__metaclass__属性,并尝试做和前面同样的操作。
如果Python在任何父类中都找不到__metaclass__,它就会在模块层次中去寻找__metaclass__,并尝试做同样的操作。
如果还是找不到__metaclass__,Python就会用内置的type来创建这个类对象。
将创建的类属性和方法全部变为大写
def up_attr(myclass,par,attrs):
attrs = ((name,value) for name,value in attrs.items())
Attrs = dict(((name.upper(),value) for name,value in attrs))
return type(myclass,par,Attrs)
__metaclass__ = up_attr #写做全局变量,整个块都以up_attr作为元类
class Foo():
bar = 3
a = 'zzz'
print(hasattr(Foo,'bar')) #False
print(hasattr(Foo,'BAR')) #True
print(hasattr(Foo,'a')) #False
print(hasattr(Foo,'A')) #True
f = Foo()
print(f.A) #zzz
'-------------------------------->'
class mytype(type):
def __new__(cls,myclass,par,attrs):
attrs = ((name,value) for name,value in attrs.items())
Attrs = dict(((name.upper(),value) for name,value in attrs))
return super(mytype,cls).__new__(cls,myclass,par,Attrs)
# __metaclass__ = mytype
class Foo:
__metaclass__ = mytype
bar = 'zzz'
def a(self):
return 'zzzzzz'
print(hasattr(Foo,'bar'))
print(hasattr(Foo,'BAR'))
print(Foo.BAR)
print(Foo().A())
'--------------------------------->'
class A:
__metaclass__ = mytype
pass
class Faa(A):
bbb = 'zzz'
def b(self):
return 'Faa'
print('------------------')
print(hasattr(Faa,'bbb'))
print(hasattr(Faa,'BBB'))
print(Faa.BBB)
print(Faa().B())
实现一种接口
抽象类:
如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类就是从一堆类中抽取相同的内容而来的,内容包括数据属性和函数属性。
从实现角度来看,抽象类与普通类的不同之处在于:抽象类中有抽象方法,该类不能被实例化,只能被继承,且子类必须实现抽象方法。
import abc
创建接口:
class Pre: #抽象类,不能被实例化
__metaclass__ = abc.ABCMeta #将这个类指定元类
@abc.abstractmethod #定义抽象方法,子类必须实现此方法
def zz(self):
raise NotImplementedError
实现接口:
class Chi(Pre):
a = 2222
def zzz(self):
return 'chi success'
def zz(self):
return 'ok ok ok '
chi = Chi()
print(chi.zz())
__all__的用法
规定含有__all__的包中哪些可以被import
foo.py:
from foo1 improt *
__all__ = [a,b]
a = 1
b = 2
c = 3
d = 10
from foo import * print(a,b) -----> (1,2)
print(a,b,c,d) -----> NameError: name 'c' is not defined
使用字符串导包
函数import()与__import__()
https://blog.csdn.net/u011502243/article/details/83929085
import导入的是一个标准模块,而标准模块的概念是一个文件夹里面必须包含__init__.py文件。它的作用更像是一种声明,且import模块进来之后,万一原本的模块有什么变化,可以通过reload()进行重新加载。
__import__()作为一个函数,只能接受字符串参数,返回值可以直接用来操作,通常在动态加载的时候用到这个函数,最常见的情景就是插件功能的支持。 ```
**sys.modules** ```sys.modules是一个全局字典,该字典是python启动后就加载在内存中。每当程序导入新的模块,sys.modules都将记录这些模块。字典sys.modules对于加载模块起到了缓冲的作用。当某个模块第一次导入,字典sys.modules将自动记录该模块。当第二次再导入该模块时,python会直接到字典中查找,从而加快了程序运行的速度。 ```
**from importlib import import_module** ```import_module 就是调用了__import__和sys.modules两个方法,并做了一些处理; 这样就可以使用import_modules直接用字符串导入包 ```例:在安装django调试工具时,需配置路径,需要用到配置文件的环境变量;而环境变量是一个字符串,不可以用import直接调用; ```
#django 调试工具配置 setting = os.environ.get('DJANGO_SETTINGS_MODULE')
#__import__(setting)
#setting= sys.modules.get(setting) setting = import_module(setting) if setting.DEBUG:
import debug_toolbar
urlpatterns.append(url(r'^__debug__/', include(debug_toolbar.urls)),) ```
**为Python添加默认模块搜索路径**
https://www.douban.com/note/334738164/
```python
python 在导包入python自有的包时,无论我们在哪里导入,使用的方式都是一样的,而在到入我们自己的包时却要根据文件的相对位置导入,这是为什么呢?
上网查了一下,主要和sys.path有关
import sys
>>> sys.path
会得到一个列表,列表中列出了很多路径
给这个列表添加一个路径,只要到路径就可以了,不需要文件名
sys.path.append('/xx/xx/xx/xx')
修改环境变量PYTHONPATH,未测试,不敢乱改
增加.pth文件
在site-packages添加一个路径文件,如mypkpath.pth,必须以.pth为后缀,写上你要加入的模块文件所在的目录
但为什么是这里呢,列表中的其他文件夹不可以 吗?
有时间测试一下!!!
函数__repr__和__str__
都是用来显示;
>>>交互页面只显示__repr__的内容;
print会显示__repr__和__str__的内容;
优先显示__str__的内容;
str更多的是给用户看,__pepr__更多的是给开发者看。
函数__dict__()
一个用来装对象属性和值的字典
看Django下默认settings的属性和值
from django.conf import global_settings
# print(dir(global_settings)) #值看属性都有哪些
print(global_settings.__dict__) #看属性和他的值
插件:https://blog.csdn.net/gqtcgq/article/details/49620279
字符串转字典
:http://www.cnblogs.com/OnlyDreams/p/7850920.html
json.loads() 要求字符串内必须为双引号
eval() 存在安全问题 __import__('os').system('dir') 会返回目录,输入删除命令可能会清除目录
ast.literal_eval() 没有问题