python 难点总结

1.回归函数

上述是廖雪峰教程中的代码。

先分析一下代码:

一个count()返回一个list,list里面的元素是3个函数。由于参数J是根据循环i(可变参数)而定,而参数的分配往往是等返回全部函数才返回参数。因此只会得到9,9,9.而上面增加了多一个def f(j)用于在每次循环都实时返回参数,所以才得到1,4,9

之前一直困惑,能不能不要def g()和return g,直接用def f(j),然后内容就直接return j×j。这样也实时返回了i。

显然是不行的,而且def f(j)这个多一层的返回函数是不能忽略。有上面的困惑最主要是我忽略了在return 中   return f return f()的差别。return f是返回函数,而return f()是直接执行函数。

也就是说执行count()后,是这样的list【g(j),g(j),g(j)】而不是我想的【f(j),f(j),f(j)】,因此要么fs.append()括号中填f而不是f(),要么就像上面增加一个返回函数f。还有网有的大神方法,如下

2.装饰器

廖雪峰装饰器作业:

答案:

import functools

def log(pointer):  #pointer是个变量,在这里能指向函数或者str,这就要看if条件
	if not isinstance(pointer,str):  #如果pointer不是字符串,pointer指向函数func,
		@functools.wraps(pointer)
		def wrapper(*args,**kw):
			print 'begin %s,test:none' % pointer.__name__
			return pointer(*args,**kw)
		return wrapper
	else:#不然的话,pointer指向str
		def decorator(func):
			@functools.wraps(func)
			def wrapper(*args,**kw):
				print 'begin %s,test:%s' % (func.__name__,pointer)
				return func(*args,**kw)
			return wrapper
		return decorator

3.元类metaclass

对象-关系映射表

#!/usr/bin/env python
# -*- coding: utf-8 -*-

#对象-关系映射表 ,先声明一下: u=user(~)
class Field(object):
	def __init__(self, name,column_type): #字段名,字段类型
		self.name = name
		self.column_type = column_type
	def __str__(self):
		#如果直接print Field,返回类的名字(这里是Field)和字段名
		return '%s:%s' %(self.__class__.__name__,self.name)

#用于定义
class StringField(Field):
	def __init__(self,name):    #super让本子类继承了两属性,name和column_type
		super(StringField,self).__init__(name,'varchar(100)')

class IntegerField(Field):
	def __init__(self,name):
		super(IntegerField,self).__init__(name,'varchar(100)')


class ModelMetaclass(type):  #创建类都需要从type中派生
	#cls是元类对象ModelMetaclass,name是类名,bases是类继承的父类集合(dict),
	# attrs是类的方法集合(就是ID,email那个,82行附近,暂时不了解为啥会等于attrs)
	def __new__(cls,name,bases,attrs):
		#如果类名是'Model',就直接返回一个类
		if name == 'Model':   #在本例中,先由name为model创立model类,然后再由名为user创立一个user类,看46行
			return type.__new__(cls,name,bases,attrs)
		#创建一个dict
		mappings = dict() 
		#抽取attrs中的集合
		for k,v in attrs.iteritems():
			#判断获取的value是否是Field类型,(Value通常是Field的子类)
			if isinstance(v,Field):
				# 打印指向实例的变量,实例信息
				print ('Found mapping: %s==%s' %(k,v))
				#如果value是FIeld类型,将该key和value放进mappings的dict中
				mappings[k] = v
		for k in mappings.iterkeys():
			#删除attrs里面被放进mappings中相同的key,对应的value也会被删除
			attrs.pop(k)
		attrs['__table__'] = name
		#python允许在dict中放入一个dict
		attrs['__mappings__'] = mappings 
		
		return type.__new__(cls,name,bases,attrs) 

class Model(dict):
	#以ModelMetaclass的__new__来创建MOdel这个类
	__metaclass__ = ModelMetaclass

	def __init__(self,**kw):     #self是一个dict,由于user继承model,model继承dict,所以在生成实例时user(参数)括号里参数是传入类似与**kw的参数,参数会自动转化成dict.
		super(Model,self).__init__(**kw)

	def __getattr__(self,key):
		#比如尝试返回u[age],没有则报错
		try:
			return self[key]
		except KeyError:
			raise AttributeError(r"'Model' object has no attribute '%s'" % key)
	
	#允许u[key] = value 赋值
	def __setattr__(self,key,value):
		self[key] =value

	def save(self):
		fields = []
		params = []
		args = []
		for k,v in self.__mappings__.iteritems(): #__mappings__存储的是84行dict
			fields.append(v.name)  #v.name是各实例中name属性的值
			params.append('?')
			args.append(getattr(self,k,None))  #k是指向实例的变量名,根据__getattr__函数返回的是
		sql = 'insert into %s (%s) values (%s)' %(self.__table__,','.join(fields),','.join(params))
		print('SQL:%s' % sql)
		print('ARGS:%s' % str(args))


class User(Model):
	# 定义类的属性到列的映射:

	# 创造了类似于这样一个dict
	# {ID:<__main.StringField object at 0x017AD830>,name:(基于StringField的实例),email:(~实例),password:(~实例)}
	# 这个dict就是等等在__new__中代入的attrs
	id = IntegerField('uid')
	name = StringField('username')
	email = StringField('email')
	password = StringField('password')

# 创建一个实例:
u = User(id=12345, name='Michael', email='test@orm.org', password='my-pwd')
# 保存到数据库:
u.save()

#输出结果如下
# Found model: User
# Found mapping: email ==> <StringField:email>
# Found mapping: password ==> <StringField:password>
# Found mapping: ID ==> <IntegerField:uid>
# Found mapping: name ==> <StringField:username>
# SQL: insert into User (password,email,username,uid) values (?,?,?,?)
# ARGS: ['my-pwd', 'test@orm.org', 'Michael', 12345]

上述代码大概思路是:

①在创建user类时,就包含了在user下的所有属性(但不包括括号里面的,比如id = 12345),就是那个id=IntegerField('uid')那4个。

②由于user类继承了model类,而model中又有__metaclass__=modemetaclass类,所以会先用modemetaclass类中的__new__()方法创建model函数,然后user在通过modemetaclass中的__new__()方法创建user函数,同时继承拥有model所有的方法和属性.

③在modemetaclass类中的__new__的大概意思是:attrs是一个字典,里面包含了4个key和value,也就是id=IntegerField('uid')那4个,id是key,=号后面的是value.判断字典中的所有值value是否继承Field类,满足的话,将那个value和对应的key都放进__mappings__这个字典中(__mappings__是新创建的dict).然后将__mappings__字典保存在attrs字典中(也即是字典中的字典),并创建一个新key(__table__)表名和值放在attrs中,同时清空attrs中有的,但__mappings中也有的相同key和值,清的是attrs中的.这是attrs只有两个key,也就是__mappings__和__table__

④上面都是创造类的,就是不会运行如下面括号中的内容,比如(id=12345,,,,)

# 创建一个实例:
u = User(id=12345, name='Michael', email='test@orm.org', password='my-pwd')

现在创建实例,就要用到括号中的参数.

虽然在创建实例和创建类时,都用了相同的属性,比如id,创建类是指向一个实例IntegerField('uid')用于判断其是否继承Field类,创建实例是id是指向一个整型12345.

由于继承dict类,所以创造实例后,变量u指向的实例实际上是一个字典.该字典就是{'id':12345,'name':'Michael'....}那4个.

4.搜索所以子目录包含有‘t’的文件

import os

def search(s,dir=os.path.abspath('.')):
    for x in os.listdir(dir):   #通过循环列出当前目录的文件及文件夹列表
        newpath=os.path.join(dir,x)  #对列表中的文件及文件夹都添加路径
        if os.path.isfile(newpath) and (s in os.path.splitext(x)[0]):  #判断是否是文件并且文件名中是否包含test字符
            print newpath  #打印路径
        if os.path.isdir(newpath):  #判断是否文件夹
            search(s,newpath)  #递归search,第二级search和第一级search中的属性互补影响

if __name__ == '__main__':
	search('test')

 

转载于:https://my.oschina.net/u/3384982/blog/902610

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值