将函数或 属性 应用于相同 class 的多个方法
Apply function or property to multiple methods of same class
在下面的示例中,class MyExample
读取文件名中包含下划线的文件名列表。
class MyExample(object):
def __init__(self, location: str):
self.location = location
def get_file_names(self):
# For simplicity, lets just return an example of the output
return ["my_file_name_01.txt", "my_file_name_02.txt"]
def get_file_name_number(self):
# Idem as before.
return ["file_name_01.txt", "file_name_02.txt"]
def get_file_size(self):
# It does not return a list of strings so the desired
# property or function will not be applied here
return [3800, 4000]
执行代码时,结果为
my_object = MyExample("./a/random/path")
print(my_object.get_file_names())
print(my_object.get_file_name_number())
print(my_object.get_file_size())
# The results:
['my_file_name_01.txt', 'my_file_name_02.txt']
['file_name_01.txt', 'file_name_02.txt']
[3800, 4000]
现在,我想找到一种方法来 应用一个函数或 属性(我们称之为 to_dot
),它可以替换下划线get_file_names()
和 get_file_name_number
输出的点。
最终代码应该 return 类似于
# Calling this function with .to_dots
my_object.get_file_names().to_dots
["my.file.name.01.txt", "my.file.name.02.txt"] # <-- The desired output
# Calling this function with .to_dots
my_object.get_file_name_number().to_dots
["file.name.01.txt", "file.name.02.txt"] # <-- The desired output
# Calling this function with .to_dots
my_object.get_file_name_number().to_dots
AttributeError # # <-- The desired output ... or something similar
有没有办法将to_dots
加到classMyExample
中,以替换里面某些方法的下划线?
我对装饰器不是很熟悉,但我怀疑这样做可能有技巧。到目前为止,我尝试使用 @property
没有成功,但据我所知,有很多类型的装饰器......或者也许没有装饰器也可以完成,我很迷茫。
谢谢。
定义你自己的装饰器:
def to_dots(func):
def inner():
original_return = func()
return [item.replace('_','.') for item in original_return ]
return inner
并将其用作:
@to_dots
def get_file_names(self):
你可以这样做:
from collections import UserList
class MyList(UserList):
@property
def to_dots(self):
return [s.replace("_", ".") for s in self.data]
class MyExample(object):
def __init__(self, location: str):
self.location = location
def get_file_names(self):
return MyList(["my_file_name_01.txt", "my_file_name_02.txt"])
结果
my_object = MyExample("./a/random/path")
print(my_object.get_file_names())
print(my_object.get_file_names().to_dots)
是
['my_file_name_01.txt', 'my_file_name_02.txt']
['my.file.name.01.txt', 'my.file.name.02.txt']
为什么不将所需的输出格式(是否带点)作为可选参数传递给这些方法?
class MyExample(object):
def __init__(self, location: str):
self.location = location
@staticmethod
def map_list(lst, dotted=False):
return [s.replace("_", ".") for s in lst] if dotted else lst
def get_file_names(self, dotted=False):
return self.map_list(["my_file_name_01.txt", "my_file_name_02.txt"], dotted)
def get_file_name_number(self, dotted=False):
return self.map_list(["file_name_01.txt", "file_name_02.txt"], dotted)
def get_file_size(self):
return [3800, 4000]
my_object = MyExample("./a/random/path")
print(my_object.get_file_names()) # Underscores untouched
print(my_object.get_file_name_number(dotted=True)) # Underscores replaced
print(my_object.get_file_size())
您可以使用 class 装饰器 将 函数装饰器 应用到指定的 class 方法。
from functools import wraps
import inspect
def dec_methods(decorator, *members):
"""Class decorator to apply specfied decorator to specified members of class."""
def dec_the_class(cls):
for name, m in inspect.getmembers(cls, inspect.isfunction):
if name in members:
setattr(cls, name, decorator(m))
return cls
return dec_the_class
def to_dots(func):
"""Function decorator to replace '_' with dots in list of strings returned."""
@wraps(func)
def wrapped(*args, **kwargs):
results = func(*args, **kwargs)
results = [result.replace('_', '.') for result in results]
return results
return wrapped
@dec_methods(to_dots, 'get_file_names', 'get_file_name_number')
class MyExample(object):
def __init__(self, location: str):
self.location = location
def get_file_names(self):
# For simplicity, lets just return an example of the output
return ["my_file_name_01.txt", "my_file_name_02.txt"]
def get_file_name_number(self):
# Idem as before.
return ["file_name_01.txt", "file_name_02.txt"]
def get_file_size(self):
# It does not return a list of strings so the desired
# property or function will not be applied here
return [3800, 4000]
my_object = MyExample("./a/random/path")
print(my_object.get_file_names()) # -> ['my.file.name.01.txt', 'my.file.name.02.txt']
print(my_object.get_file_name_number()) # -> ['file.name.01.txt', 'file.name.02.txt']
print(my_object.get_file_size()) # -> [3800, 4000]
在下面的示例中,class MyExample
读取文件名中包含下划线的文件名列表。
class MyExample(object):
def __init__(self, location: str):
self.location = location
def get_file_names(self):
# For simplicity, lets just return an example of the output
return ["my_file_name_01.txt", "my_file_name_02.txt"]
def get_file_name_number(self):
# Idem as before.
return ["file_name_01.txt", "file_name_02.txt"]
def get_file_size(self):
# It does not return a list of strings so the desired
# property or function will not be applied here
return [3800, 4000]
执行代码时,结果为
my_object = MyExample("./a/random/path")
print(my_object.get_file_names())
print(my_object.get_file_name_number())
print(my_object.get_file_size())
# The results:
['my_file_name_01.txt', 'my_file_name_02.txt']
['file_name_01.txt', 'file_name_02.txt']
[3800, 4000]
现在,我想找到一种方法来 应用一个函数或 属性(我们称之为 to_dot
),它可以替换下划线get_file_names()
和 get_file_name_number
输出的点。
最终代码应该 return 类似于
# Calling this function with .to_dots
my_object.get_file_names().to_dots
["my.file.name.01.txt", "my.file.name.02.txt"] # <-- The desired output
# Calling this function with .to_dots
my_object.get_file_name_number().to_dots
["file.name.01.txt", "file.name.02.txt"] # <-- The desired output
# Calling this function with .to_dots
my_object.get_file_name_number().to_dots
AttributeError # # <-- The desired output ... or something similar
有没有办法将to_dots
加到classMyExample
中,以替换里面某些方法的下划线?
我对装饰器不是很熟悉,但我怀疑这样做可能有技巧。到目前为止,我尝试使用 @property
没有成功,但据我所知,有很多类型的装饰器......或者也许没有装饰器也可以完成,我很迷茫。
谢谢。
定义你自己的装饰器:
def to_dots(func):
def inner():
original_return = func()
return [item.replace('_','.') for item in original_return ]
return inner
并将其用作:
@to_dots
def get_file_names(self):
你可以这样做:
from collections import UserList
class MyList(UserList):
@property
def to_dots(self):
return [s.replace("_", ".") for s in self.data]
class MyExample(object):
def __init__(self, location: str):
self.location = location
def get_file_names(self):
return MyList(["my_file_name_01.txt", "my_file_name_02.txt"])
结果
my_object = MyExample("./a/random/path")
print(my_object.get_file_names())
print(my_object.get_file_names().to_dots)
是
['my_file_name_01.txt', 'my_file_name_02.txt']
['my.file.name.01.txt', 'my.file.name.02.txt']
为什么不将所需的输出格式(是否带点)作为可选参数传递给这些方法?
class MyExample(object):
def __init__(self, location: str):
self.location = location
@staticmethod
def map_list(lst, dotted=False):
return [s.replace("_", ".") for s in lst] if dotted else lst
def get_file_names(self, dotted=False):
return self.map_list(["my_file_name_01.txt", "my_file_name_02.txt"], dotted)
def get_file_name_number(self, dotted=False):
return self.map_list(["file_name_01.txt", "file_name_02.txt"], dotted)
def get_file_size(self):
return [3800, 4000]
my_object = MyExample("./a/random/path")
print(my_object.get_file_names()) # Underscores untouched
print(my_object.get_file_name_number(dotted=True)) # Underscores replaced
print(my_object.get_file_size())
您可以使用 class 装饰器 将 函数装饰器 应用到指定的 class 方法。
from functools import wraps
import inspect
def dec_methods(decorator, *members):
"""Class decorator to apply specfied decorator to specified members of class."""
def dec_the_class(cls):
for name, m in inspect.getmembers(cls, inspect.isfunction):
if name in members:
setattr(cls, name, decorator(m))
return cls
return dec_the_class
def to_dots(func):
"""Function decorator to replace '_' with dots in list of strings returned."""
@wraps(func)
def wrapped(*args, **kwargs):
results = func(*args, **kwargs)
results = [result.replace('_', '.') for result in results]
return results
return wrapped
@dec_methods(to_dots, 'get_file_names', 'get_file_name_number')
class MyExample(object):
def __init__(self, location: str):
self.location = location
def get_file_names(self):
# For simplicity, lets just return an example of the output
return ["my_file_name_01.txt", "my_file_name_02.txt"]
def get_file_name_number(self):
# Idem as before.
return ["file_name_01.txt", "file_name_02.txt"]
def get_file_size(self):
# It does not return a list of strings so the desired
# property or function will not be applied here
return [3800, 4000]
my_object = MyExample("./a/random/path")
print(my_object.get_file_names()) # -> ['my.file.name.01.txt', 'my.file.name.02.txt']
print(my_object.get_file_name_number()) # -> ['file.name.01.txt', 'file.name.02.txt']
print(my_object.get_file_size()) # -> [3800, 4000]