我在尝试为程序编写一个漂亮的打印过程时遇到了这个问题,在这个程序中我使用了几个包含浮点对的命名元组。
ALTER PROCEDURE [dbo].[MyStoredProcedure]
(
@FromYears NVARCHAR(MAX), // will be 2005$Format2009$Format2013
@ToYears NVARCHAR(MAX), // will be 2008$Format2012$Format2017
@CompanyAddresses NVARCHAR(MAX), // will be string$Formatstring$Formatstring
@ProgrammingLanguages NVARCHAR(MAX), // will be Javascript$FormatC++$FormatC#
@MemberAddress NVARCHAR(MAX),
@FullName NVARCHAR(MAX),
@BirthDate DATETIME,
@TelephoneNumber NVARCHAR(MAX)
)
AS
BEGIN
DECLARE
@MemberCount INT,
@FromYear INT,
@ToYear INT,
@CompanyAddress NVARCHAR(MAX),
@ProgrammingLanguage NVARCHAR(MAX)
DECLARE @FromYearTable TABLE (
[ID] INT IDENTITY,
[FromYear] INT NOT NULL
)
DECLARE @ToYearTable TABLE (
[ID] INT IDENTITY,
[ToYear] INT NOT NULL
)
DECLARE @CompanyAddressTable TABLE (
[ID] INT IDENTITY,
[CompanyAddress] NVARCHAR(MAX) NOT NULL
)
DECLARE @ProgrammingLanguageTable TABLE (
[ID] INT IDENTITY,
[ProgrammingLanguage] NVARCHAR(MAX) NOT NULL
)
DECLARE @MemberTable TABLE (
[ID] INT IDENTITY,
[FromYear] INT NOT NULL,
[ToYear] INT NOT NULL,
[CompanyAddress] NVARCHAR(MAX) NOT NULL,
[ProgrammingLanguage] NVARCHAR(MAX) NOT NULL
)
INSERT INTO @FromYearTable
SELECT [SplittedItem] FROM [StringSplit] (@FromYears, '$Format')
INSERT INTO @ToYearTable
SELECT [SplittedItem] FROM [StringSplit] (@ToYears, '$Format')
INSERT INTO @CompanyAddressTable
SELECT [SplittedItem] FROM [StringSplit] (@CompanyAddresses, '$Format')
INSERT INTO @ProgrammingLanguageTable
SELECT [SplittedItem] FROM [StringSplit] (@ProgrammingLanguages, '$Format')
INSERT INTO @MemberTable
SELECT a.[FromYear], b.[ToYear], c.[CompanyAddress], d.[ProgrammingLanguage]
FROM @FromYearTable a
INNER JOIN @ToYearTable b ON a.[ID] = b.[ID]
INNER JOIN @CompanyAddressTable c ON a.[ID] = c.[ID]
INNER JOIN @ProgrammingLanguageTable d ON a.[ID] = d.[ID]
/*
Will be like:
ID FromYear ToYear CompanyAddress ProgrammingLanguage
1 2005 2008 string Javascript
2 2009 2012 string C++
3 2013 2017 string C#
*/
SET @MemberCount = (SELECT COUNT(*) FROM @MemberTable)
WHILE (@MemberCount > 0)
BEGIN
SET @FromYear = (SELECT TOP 1 [FromYear] FROM @MemberTable WHERE [ID] = @MemberCount)
SET @ToYear = (SELECT TOP 1 [ToYear] FROM @MemberTable WHERE [ID] = @MemberCount)
SET @CompanyAddress = (SELECT TOP 1 [CompanyAddress] FROM @MemberTable WHERE [ID] = @MemberCount)
SET @ProgrammingLanguage = (SELECT TOP 1 [ProgrammingLanguage] FROM @MemberTable WHERE [ID] = @MemberCount)
INSERT INTO [MyTable] (@FromYear, @ToYear, @CompanyAddress, @ProgrammingLanguage, @MemberAddress, @FullName, @BirthDate, @TelephoneNumber)
SET @MemberCount -= 1
END
END
我想在打印时格式化浮点数,因为结果为:
from collections import namedtuple
Position = namedtuple('Position', 'x y')
Vector = namedtuple('Vector', 'x y')
Size = namedtuple('Size', 'width height')
太长了:
import math
print(Position(math.pi, math.pi), Vector(math.pi, math.pi), Size(math.pi, math.pi))
所以我创建了一个打印命名元组的函数:
Position(x=3.141592653589793, y=3.141592653589793) Vector(x=3.141592653589793, y=3.141592653589793) Size(width=3.141592653589793, height=3.141592653589793)
每个类型的名称和标签都应该是固定的,只有obj参数不同,所以我认为我可以使用functools partial。
def pretty_float_pair(name, labels, obj):
"""
If labels = ('a', 'b') and object = (1.2345, 1.2345) returns:
'name(a=1.23, b=1.23)'
"""
return '{}({}={:.2f}, {}={:.2f})'.format(name, labels[0], obj[0], labels[1], obj[1])
但这会引发from functools import partial
Position.__str__ = partial(pretty_float_pair, 'Position', ('x', 'y'))
Vector.__str__ = partial(pretty_float_pair, 'Vector', ('x', 'y'))
Size.__str__ = partial(pretty_float_pair, 'Size', ('width', 'height'))
print(Position(math.pi, math.pi), Vector(math.pi, math.pi), Size(math.pi, math.pi))
令人惊讶的是,如果我使用lambda创建它可以运行的函数。
TypeError: pretty_float_pair() missing 1 required positional argument: 'obj'.
打印我想要的东西:
Position.__str__ = lambda x: pretty_float_pair('Position', ('x', 'y'), x)
Vector.__str__ = lambda x: pretty_float_pair('Vector', ('x', 'y'), x)
Size.__str__ = lambda x: pretty_float_pair('Size', ('width', 'height'), x)
print(Position(math.pi, math.pi), Vector(math.pi, math.pi), Size(math.pi, math.pi))
我试图理解为什么部分版本不起作用。
答案 0 :(得分:3)
functools.partial
返回非描述符可调用,大致相当于未绑定方法。这意味着它没有传递self
参数,这与您看到的错误一致。
由于lambda的行为与使用def
定义的常规函数一样,因此它实际上是一个描述符。 lambda的__get__
方法返回一个绑定版本,该版本在实例中传递为x
。
要获得行为更像方法的部分函数,请改用functools.partialmethod
。您必须将obj
移动到参数列表的开头,以便在绑定方法时接收self
。
以下是您的示例:
from functools import partialmethod def pretty_float_pair(obj, name, labels): """ If labels = ('a', 'b') and object = (1.2345, 1.2345), returns: name(a=1.23, b=1.23) """ return '{}({}={:.2f}, {}={:.2f})'.format(name, labels[0], obj[0], labels[1], obj[1]) Position.__str__ = partialmethod(pretty_float_pair, 'Position', ('x', 'y')) Vector.__str__ = partialmethod(pretty_float_pair, 'Vector', ('x', 'y')) Size.__str__ = partialmethod(pretty_float_pair, 'Size', ('width', 'height')) print(Position(math.pi, math.pi), Vector(math.pi, math.pi), Size(math.pi, math.pi))
答案 1 :(得分:1)
函数通过descriptors获取其隐式self
参数:lookup x.f
构造并返回一个记住x
的方法对象,以便将其提供给{{1} }}。 f
不返回描述符,因此它没有得到特殊处理。 (它实际上是一个类,所以它"返回"它自己的一个实例。)