本篇文章给大家谈谈错误使用__new__生成类?,以及错误使用regress(line62)的知识点,同时本文还将给你拓展oracleover的使用_____________转N、python__ne
本篇文章给大家谈谈错误使用__new__生成类?,以及错误使用regress(line62)的知识点,同时本文还将给你拓展oracle over的使用_____________转N、python __new__ 和 __init__、python __new__, __del__, super、python __new__和__init__的区别等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:- 错误使用__new__生成类?(错误使用regress(line62))
- oracle over的使用_____________转N
- python __new__ 和 __init__
- python __new__, __del__, super
- python __new__和__init__的区别
错误使用__new__生成类?(错误使用regress(line62))
我正在创建一些类来处理各种类型的文件共享(nfs,afp,s3,本地磁盘)等中的文件名。当用户输入时,会得到一个标识数据源(即"nfs://192.168.1.3"
或"s3://mybucket/data"
)的字符串。
我从具有通用代码的基类中继承特定文件系统。我感到困惑的是对象创建。我有以下内容:
import osclass FileSystem(object): class NoAccess(Exception): pass def __new__(cls,path): if cls is FileSystem: if path.upper().startswith(''NFS://''): return super(FileSystem,cls).__new__(Nfs) else: return super(FileSystem,cls).__new__(LocalDrive) else: return super(FileSystem,cls).__new__(cls,path) def count_files(self): raise NotImplementedErrorclass Nfs(FileSystem): def __init__ (self,path): pass def count_files(self): passclass LocalDrive(FileSystem): def __init__(self,path): if not os.access(path, os.R_OK): raise FileSystem.NoAccess(''Cannot read directory'') self.path = path def count_files(self): return len([x for x in os.listdir(self.path) if os.path.isfile(os.path.join(self.path, x))])data1 = FileSystem(''nfs://192.168.1.18'')data2 = FileSystem(''/var/log'')print type(data1)print type(data2)print data2.count_files()
我以为这会很好用,__new__
但我读过的大多数文章都劝阻它。有没有更公认的方法来解决此问题?
答案1
小编典典我 不
认为用__new__()
做你想要的东西是不正确的。换句话说,我不同意这个问题)的公认答案,该观点认为工厂功能始终是“最佳方法”。
如果您真的想避免使用它,则唯一的选择是元类或单独的工厂函数/方法。考虑到可用的选择,将__new__()
方法设置为一种(因为默认情况下是静态的)是一种完全明智的方法。
也就是说,以下是我认为是代码的改进版本。我添加了几个类方法来帮助自动查找所有子类。它们支持更好的最重要方法-
现在添加子类不需要修改__new__()
方法。这意味着它现在很容易扩展,因为它有效地支持了所谓的 虚拟构造函数 。
也可以使用类似的实现将实例的创建从__new__()
方法中移到单独的(静态)工厂方法中-
因此,从某种意义上说,无论使用什么名称,所示技术都是一种相对简单的编码可扩展通用工厂函数的方法它给出了。
# Works in Python 2 and 3.import osimport reclass FileSystem(object): class NoAccess(Exception): pass class Unknown(Exception): pass # Regex for matching "xxx://" where x is any non-whitespace character except for ":". _PATH_PREFIX_PATTERN = re.compile(r''\s*([^:]+)://'') @classmethod def _get_all_subclasses(cls): """ Recursive generator of all class'' subclasses. """ for subclass in cls.__subclasses__(): yield subclass for subclass in subclass._get_all_subclasses(): yield subclass @classmethod def _get_prefix(cls, s): """ Extract any file system prefix at beginning of string s and return a lowercase version of it or None when there isn''t one. """ match = cls._PATH_PREFIX_PATTERN.match(s) return match.group(1).lower() if match else None def __new__(cls, path): """ Create instance of appropriate subclass using path prefix. """ path_prefix = cls._get_prefix(path) for subclass in cls._get_all_subclasses(): if subclass.prefix == path_prefix: # Using "object" base class method avoids recursion here. return object.__new__(subclass) else: # No subclass with matching prefix found (& no default defined) raise FileSystem.Unknown( ''path "{}" has no known file system prefix''.format(path)) def count_files(self): raise NotImplementedErrorclass Nfs(FileSystem): prefix = ''nfs'' def __init__ (self, path): pass def count_files(self): passclass LocalDrive(FileSystem): prefix = None # Default when no file system prefix is found. def __init__(self, path): if not os.access(path, os.R_OK): raise FileSystem.NoAccess(''Cannot read directory'') self.path = path def count_files(self): return sum(os.path.isfile(os.path.join(self.path, filename)) for filename in os.listdir(self.path))if __name__ == ''__main__'': data1 = FileSystem(''nfs://192.168.1.18'') data2 = FileSystem(''c:/'') # Change as necessary for testing. print(type(data1).__name__) # -> Nfs print(type(data2).__name__) # -> LocalDrive print(data2.count_files()) # -> <some number>
Python 3.6+更新
上面的代码可在Python 2和3.x中使用。但是,在Python
3.6中,object
为named添加了一个新的类方法,__init_subclass__()
该方法通过使用子类自动创建子类的“注册表”来简化子类的查找,而不必像上述_get_all_subclasses()
方法那样递归地检查每个子类。
# Requires Python 3.6+import osimport reclass FileSystem(object): class NoAccess(Exception): pass class Unknown(Exception): pass # Regex for matching "xxx://" where x is any non-whitespace character except for ":". _PATH_PREFIX_PATTERN = re.compile(r''\s*([^:]+)://'') _registry = {} # Registered subclasses. @classmethod def __init_subclass__(cls, /, path_prefix, **kwargs): super().__init_subclass__(**kwargs) cls._registry[path_prefix] = cls # Add class to registry. @classmethod def _get_prefix(cls, s): """ Extract any file system prefix at beginning of string s and return a lowercase version of it or None when there isn''t one. """ match = cls._PATH_PREFIX_PATTERN.match(s) return match.group(1).lower() if match else None def __new__(cls, path): """ Create instance of appropriate subclass. """ path_prefix = cls._get_prefix(path) subclass = FileSystem._registry.get(path_prefix) if subclass: # Using "object" base class method avoids recursion here. return object.__new__(subclass) else: # No subclass with matching prefix found (and no default). raise FileSystem.Unknown( f''path "{path}" has no known file system prefix'') def count_files(self): raise NotImplementedErrorclass Nfs(FileSystem, path_prefix=''nfs''): def __init__ (self, path): pass def count_files(self): passclass LocalDrive(FileSystem, path_prefix=None): # Default file system. def __init__(self, path): if not os.access(path, os.R_OK): raise FileSystem.NoAccess(''Cannot read directory'') self.path = path def count_files(self): return sum(os.path.isfile(os.path.join(self.path, filename)) for filename in os.listdir(self.path))if __name__ == ''__main__'': data1 = FileSystem(''nfs://192.168.1.18'') data2 = FileSystem(''c:/'') # Change as necessary for testing. print(type(data1).__name__) # -> Nfs print(type(data2).__name__) # -> LocalDrive print(data2.count_files()) # -> <some number> try: data3 = FileSystem(''foobar://42'') # Unregistered path prefix. except FileSystem.Unknown as exc: print(str(exc), ''- raised as expected'') else: raise RuntimeError( "Unregistered path prefix should have raised Exception!")
oracle over的使用_____________转N
Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是
对于每个组返回多行,而聚合函数对于每个组只返回一行。
下面通过几个例子来说明其应用。
1 20
2 15
3 14
4 18
5 30
规则:按天统计:每天都统计前面几天的总额
得到的结果:
DATE SALE SUM
----- -------- ------
1 20 20 --1天
2 15 35 --1天+2天
3 14 49 --1天+2天+3天
4 18 67 .
5 30 97 .
2:统计各班成绩第一名的同学信息
----- ----- ----------------------
fda 1 80
ffd 1 78
dss 1 95
cfe 2 74
gds 2 92
gf 3 99
ddd 3 99
adf 3 45
asdf 3 55
3dd 3 78
通过:
--
select * from
(
select name,class,s,rank()over(partition by class order by s desc) mm from t2
)
where mm=1
--
得到结果:
NAME CLASS S MM
----- ----- ---------------------- ----------------------
dss 1 95 1
gds 2 92 1
gf 3 99 1
ddd 3 99 1
注意:
1.在求第一名成绩的时候,不能用row_number(),因为如果同班有两个并列第一,row_number()只返回一个结果
2.rank()和dense_rank()的区别是:
--rank()是跳跃排序,有两个第二名时接下来就是第四名
--dense_rank()l是连续排序,有两个第二名时仍然跟着第三名
3.分类统计 (并显示信息)
-- -- ----------------------
m a 2
n a 3
m a 2
n b 2
n b 1
x b 3
x b 2
x b 4
h b 3
得到结果:
A B C SUM(C)OVER(PARTITIONBYA)
-- -- ------- ------------------------
h b 3 3
m a 2 4
m a 2 4
n a 3 6
n b 2 6
n b 1 6
x b 3 9
x b 2 9
x b 4 9
如果用sum,group by 则只能得到
A SUM(C)
-- ----------------------
h 3
m 4
n 6
x 9
无法得到B列值
=====
select * from test
数据:
A B C
1 1 1
1 2 2
1 3 3
2 2 5
3 4 6
---将B栏位值相同的对应的C 栏位值加总
select a,b,c, SUM(C) OVER (PARTITION BY B) C_Sum
from test
A B C C_SUM
1 1 1 1
1 2 2 7
2 2 5 7
1 3 3 3
3 4 6 6
---如果不需要已某个栏位的值分割,那就要用 null
eg: 就是将C的栏位值summary 放在每行后面
select a,b,c, SUM(C) OVER (PARTITION BY null) C_Sum
from test
A B C C_SUM
1 1 1 17
1 2 2 17
1 3 3 17
2 2 5 17
3 4 6 17
求个人工资占部门工资的百分比
SQL> select * from salary;
NAME DEPT SAL
---------- ---- -----
a 10 2000
b 10 3000
c 10 5000
d 20 4000
SQL> select name,dept,sal,sal*100/sum(sal) over(partition by dept) percent from salary;
NAME DEPT SAL PERCENT
---------- ---- ----- ----------
a 10 2000 20
b 10 3000 30
c 10 5000 50
d 20 4000 100
开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化,举例如下:
1:
over(order by salary) 按照salary排序进行累计,order by是个默认的开窗函数
over(partition by deptno)按照部门分区
2:
over(order by salary range between 5 preceding and 5 following)
每行对应的数据窗口是之前行幅度值不超过5,之后行幅度值不超过5
例如:对于以下列
aa
1
2
2
2
3
4
5
6
7
9
sum(aa)over(order by aa range between 2 preceding and 2 following)
得出的结果是
AA SUM
---------------------- -------------------------------------------------------
1 10
2 14
2 14
2 14
3 18
4 18
5 22
6 18
7 22
9 9
就是说,对于aa=5的一行 ,sum为 5-1<=aa<=5+2 的和
对于aa=2来说 ,sum=1+2+2+2+3+4=14 ;
又如 对于aa=9 ,9-1<=aa<=9+2 只有9一个数,所以sum=9 ;
3:其它:
over(order by salary rows between 2 preceding and 4 following)
每行对应的数据窗口是之前2行,之后4行
4:下面三条语句等效:
over(order by salary rows between unbounded preceding and unbounded following)
每行对应的数据窗口是从第一行到最后一行,等效:
over(order by salary range between unbounded preceding and unbounded following)
等效
over(partition by null)
python __new__ 和 __init__
概述
new 和 init 是类实例化的过程中被调用的方法, new 负责对象的创建,相当于构造器或者构造函数; init 负责对象初始化。 使用频率上, init 较多会被使用。
class A(object):
def __new__(cls):
return object.__new__(cls)
def __init__(self):
self.instance_method()
def instance_method(self):
print ''success!''
newA = A()
区别
参数
new 的第一个参数是 cls,表示类本身。
而 init 类似一般的实例方法, 第一个参数是 self,表示实例。我们可以看到 init 方法运行之前, 实例已经可以被使用了(self参数)。实例上的其他的方法也是可以使用的了。
调用时机
当我们创建类的对象时, new 先被调用,返回一个对象,对象引用作为参数传递给 init__, 然后对象属性被初始化。__init 方法不能返回任何数据。
__new__ --->(创建对象) --> __init__(self)
使用
只有很少的时候需要自己编写 new 方法,比如单例模式。大多数情况下,只需要关心实例的初始化,初始化过程中属性的分配,以及是否调用其他的实例方法。
以上代码和经验仅在 Python(2.7) 得到验证。
python __new__, __del__, super
1. __new__() 类“构造器”方法
__new__()方法是类的构造器,返回类实例。Python 用户可以对内建类型进行派生,因此,需要一种途径来实例化不可变对象,比如,派生字符串,数字,等等。在这种情况下,解释器则调用类的__new__()方法,__new__()会调用父类的__new__()来创建对象(向上代理)。调用__new__时,需要一个传入参数 cls,cls就是__new__方法返回的实例所属的类。
>>> class float2(float):
def __new__(cls, arg = 0):
return round(float.__new__(cls, arg),2)
>>> a = float2(1.3333)
>>> a
1.33
2. __del__() 类"解构器"方法
由于 Python 具有垃圾对象回收机制(靠引用计数),这个函数要直到该实例对象所有的引用都被清除掉后才会执行。
del 语句删除一个对象的引用,当引用计数为0时,会调用__del__方法。Python 中的解构器是在实例释放前提供特殊处理功能的方法,它们通常没有被实现,因为实例很少被显式释放。
3. super()
super()函数在新式类中引入,用这个函数可以找出的父类,然后调用父类相关的属性。一般情况下,程序员可能仅仅采用非绑定方式调用祖先类方法。super语法如下:
super(type[, obj])
给出 type, super()“返回此 type 的父类”。如果你希望父类被绑定,你可以传入 obj 参数(obj必须是 type 类型的).否则父类不会被绑定。obj 参数也可以是一个类型,但它应当是 type 的一个子类。通常,当给出 obj 时:
如果 obj 是一个实例,isinstance(obj,type)就必须返回 True
如果 obj 是一个类或类型,issubclass(obj,type)就必须返回 True
来看看单例模式如何实现,最简单的想到使用类属性。
>>> class Singleton(object):
_instance = None
def __new__(cls, *args, **kwargs):
print cls.__name__, Singleton.__name__
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance
>>> a = Singleton()
Singleton Singleton
>>> b = Singleton()
Singleton Singleton
>>> id(a),id(b)
(47568656L, 47568656L)
类Singleton定义中,cls实际就是Singleton,隐藏可以写成
cls._instance = super(cls, cls).__new__(cls, *args, **kwargs)
python __new__和__init__的区别
__new__和__init__的区别
# new 是用来控制对象的生成过程,在对象生成之前
# init 是用来完善对象的
# 如果new方法不返回对象,则不会调用init方法
class User:
def __new__(cls, *args, **kwargs):
print("in new")
return super().__new__(cls)
def __init__(self, name):
print("in init")
self.name = name
if __name__ == ''__main__'':
user = User(name="abc")
今天关于错误使用__new__生成类?和错误使用regress(line62)的分享就到这里,希望大家有所收获,若想了解更多关于oracle over的使用_____________转N、python __new__ 和 __init__、python __new__, __del__, super、python __new__和__init__的区别等相关知识,可以在本站进行查询。
本文标签: