针对昨天的疑惑,做一下以下学习笔记
==原问题:==
python
class Privileges:
"""定义权限的属性"""
def __init__(self,privileges=['can add post','can delete post','can ban user']):
self.privileges = privileges
def show_privileges(self):
"""打印管理员的权限"""
print("作为管理员,具有权限如下:")
for i in self.privileges:
print(f"\n{i}")
# **上述代码中,为什么不可以写成以下的:**
class Privileges:
"""定义权限的属性"""
def __init__(self,privileges):
self.privileges = ['can add post','can delete post','can ban user']
def show_privileges(self):
"""打印管理员的权限"""
print("作为管理员,具有权限如下:")
for i in self.privileges:
print(f"\n{i}")
==这两种写法在功能上是不同的,详细区别:==
两种写法的区别:
写法1(原代码):
ruby
class Privileges:
def __init__(self, privileges=['can add post', 'can delete post', 'can ban user']):
self.privileges = privileges
特点:允许用户在创建实例时传入自定义的权限列表
写法2:
ruby
class Privileges:
def __init__(self, privileges): # 这个参数完全没用!
self.privileges = ['can add post', 'can delete post', 'can ban user']
问题 :privileges参数完全被忽略,无论传入什么都会用固定列表
实际使用对比:
python
# 测试两种写法
print("=== 写法1:使用默认参数 ===")
class Privileges1:
def __init__(self, privileges=['can add post', 'can delete post', 'can ban user']):
self.privileges = privileges
def show(self):
print(f"权限: {self.privileges}")
# 用法多样
p1_default = Privileges1() # 使用默认权限
p1_custom = Privileges1(['can edit', 'can view']) # 自定义权限
print("默认实例:", end=" "); p1_default.show()
print("自定义实例:", end=" "); p1_custom.show()
print("\n=== 写法2:忽略参数 ===")
class Privileges2:
def __init__(self, privileges): # 参数被忽略!
self.privileges = ['can add post', 'can delete post', 'can ban user'] # 固定
def show(self):
print(f"权限: {self.privileges}")
# 必须传参数,但参数被忽略
# p2 = Privileges2() # 会报错:缺少参数
p2 = Privileges2(['can edit', 'can view']) # 传入的参数被忽略
print("实例(传入的参数被忽略):", end=" "); p2.show()
更好的实现方式:
版本1:最推荐的做法
python
class Privileges:
"""管理员权限类"""
DEFAULT_PRIVILEGES = ['can add post', 'can delete post', 'can ban user']
def __init__(self, privileges=None):
"""初始化权限
参数:
privileges: 权限列表,如果为None则使用默认权限
"""
if privileges is None:
self.privileges = self.DEFAULT_PRIVILEGES.copy() # 使用副本
else:
self.privileges = privileges
def show_privileges(self):
"""显示所有权限"""
if not self.privileges:
print("该用户没有任何特殊权限")
return
print("👑 管理员权限列表:")
for i, privilege in enumerate(self.privileges, 1):
print(f" {i}. {privilege}")
def add_privilege(self, privilege):
"""添加权限"""
if privilege not in self.privileges:
self.privileges.append(privilege)
print(f"✅ 已添加权限: {privilege}")
else:
print(f"⚠️ 权限 {privilege} 已存在")
def remove_privilege(self, privilege):
"""移除权限"""
if privilege in self.privileges:
self.privileges.remove(privilege)
print(f"✅ 已移除权限: {privilege}")
else:
print(f"❌ 权限 {privilege} 不存在")
# 测试
print("=== 测试权限类 ===")
admin1 = Privileges() # 使用默认权限
print("管理员1(默认权限):")
admin1.show_privileges()
print("\n管理员2(自定义权限):")
admin2 = Privileges(['can edit posts', 'can manage users', 'can view reports'])
admin2.show_privileges()
print("\n添加新权限:")
admin1.add_privilege('can manage settings')
admin1.add_privilege('can add post') # 尝试添加已存在的权限
admin1.show_privileges()
版本2:与Admin类结合
python
class Privileges:
"""权限管理"""
def __init__(self, privileges=None):
self.privileges = privileges or ['can add post', 'can delete post', 'can ban user']
def show(self):
print("拥有的权限:")
for priv in self.privileges:
print(f" - {priv}")
class Admin:
"""管理员用户"""
def __init__(self, username, email, privileges=None):
self.username = username
self.email = email
self.privileges = Privileges(privileges) # 组合
def show_info(self):
print(f"\n管理员: {self.username}")
print(f"邮箱: {self.email}")
self.privileges.show()
# 创建管理员
admin_john = Admin("john_doe", "john@example.com")
admin_jane = Admin("jane_smith", "jane@example.com",
['can manage system', 'can audit logs'])
admin_john.show_info()
admin_jane.show_info()
为什么写法2有问题?
ruby
# 写法2的问题
class Privileges:
def __init__(self, privileges): # 这个参数必须传
# 但这里完全忽略了传入的privileges参数!
self.privileges = ['固定的默认列表'] # 总是用这个
# 使用时:
p = Privileges(['用户传入的列表']) # 用户传入了,但被忽略了
# 无论传入什么,都是固定的列表,这很令人困惑
最佳实践建议:
-
使用默认参数时小心可变对象:
python# 危险:列表是可变对象 def __init__(self, privileges=[]): # ❌ 不要这样 # 安全:使用None作为默认值 def __init__(self, privileges=None): # ✅ if privileges is None: privileges = ['默认1', '默认2'] -
明确参数用途:
ruby# 好的:参数被实际使用 def __init__(self, privileges=None): self.privileges = privileges or self.DEFAULT_PRIVILEGES # 不好的:参数被忽略 def __init__(self, privileges): # 参数没用 self.privileges = ['固定列表'] # 总是这个 -
提供清晰的文档:
pythonclass Privileges: """ 权限管理类 参数: privileges: 权限列表,可选。如果不提供则使用默认权限 """
结论:
原写法更好,因为它:
-
允许用户自定义权限
-
提供了合理的默认值
-
参数被实际使用
而第二种写法中,privileges参数完全被浪费了,这让使用者困惑。