2017-07-24 17 views
0

这里是新程序员,我在理解这个特定情况时遇到了一些麻烦,在本练习中使用点符号从Eric Matthes的Python Crash Course。这个练习来自第9章(9-11 Imported Admin),它介绍了带有类的面向对象编程。该练习要求我导入一个模块,其中包含用于为用户建模的类集合,然后向管理员用户添加某些特权。下面是我在导入模块:Python 3关于点符号的困惑使用

"""A collection of classes for modeling users.""" 

class User(): 
"""Represents a simple user profile.""" 

def __init__(self, first_name, last_name, username, email, location): 
    """Initialize attributes to decribe the user.""" 
    self.first_name = first_name.title() 
    self.last_name = last_name.title() 
    self.username = username 
    self.email = email 
    self.location = location.title() 
    self.login_attempts = 0 

def describe_user(self): 
    """Print a summary of the user's information.""" 
    print("\n" + self.first_name + " " + self.last_name) 
    print(" Username: " + self.username)   
    print(" Email: " + self.email) 
    print(" Location: " + self.location) 

def greet_user(self): 
    """Print a personalized message to the user.""" 
    print("\nHello, " + self.username) 

def increment_login_attempts(self): 
    """increment the value of login_attempts.""" 
    self.login_attempts += 1 

def reset_login_attempts(self): 
    """reset login attempts back to 0.""" 
    self.login_attempts = 0 

class Admin(User): 
"""Represents an administrator, a specific type of User.""" 

def __init__(self, first_name, last_name, username, email, location): 
    """ 
    Initialize attritbutes of parent class. 
    Then intialize attributes specific to admin. 
    """ 
    super().__init__(first_name, last_name, username, email, location) 

    self.privileges = Privileges() #instance attribute? Slightly confused here. 

class Privileges(): 
"""Class to store an admin's privileges.""" 

def __init__(self, privileges=[]): 
    """Initialize attributes for privileges.""" 
    self.privileges = privileges 

def show_privileges(self): 
    """Display the privileges the Admin has.""" 
    print("\nPrivileges:") 
    if self.privileges: 
     for privilege in self.privileges: 
      print("- " + privilege) 
    else: 
     print("- This user has no privileges.") 

我理解这个模块的工作原理在大多数情况下,除非我有self.privileges = Privileges()。我认为这是类Admin(User)的一个属性,它指向'Privileges()'类中的内容。 (抱歉不适当词的选择)

演习的第二部分是我导入模块,并建立联系的一个实例,然后添加某些特权:

"""Import class Admin(User)""" 
from user import Admin 

"""Create admin instance.""" 
bertrand = Admin('bertrand', 'russell', 'bruss,' '[email protected]','united kingdom') 
bertrand.describe_user() # Apply method from parent class User() 

"""Add admin privileges.""" 
bertrand_privileges = ['can add post', 
       'can delete post', 
       'can delete user', 
       ] 

bertrand.privileges.privileges = bertrand_privileges #I don't understand this! 

"""Concatenate and apply method to show added privileges.""" 
print("\nThe admin " + bertrand.username + 
    " has these privileges: ") 
bertrand.privileges.show_privileges() 

在考虑线bertrand.privileges.show_privileges(),我是正确认为.privileges告诉Python查看实例bertrand并找到privileges属性,因此它可以调用Privileges()类中的方法show_privileges

但是,我的主要误解是行bertrand.privileges.privileges = bertrand_privileges。 为什么第二个.privileges?如果这条线与bertrand.privileges.show_privileges()线有任何相似之处,那么第二个.privileges试图参考什么?当我删除第二个.privileges并运行代码时,出现错误。所以我认为它一定有一些目的。任何帮助,将不胜感激。也许我只是误解了我对这个实例属性的工作原理的理解?另外,为什么这种方法有用?

回答

-1

你的第一个假设是正确的。

问题的第二部分发生的事情几乎是一样的。您正在抓取实例属性bertrand.priveleges,它是Privileges类的实例化版本。由于它是没有参数实例化的,因此使用Privileges类init中的关键字参数,或者使用空列表。

现在当你做bertrand.priveleges.priveleges时,你会得到一个空的列表,但是因为你设置这个变量为“bertrand_priveleges”,这是包含bertrand的privelages的列表,现在bertrand.priveleges.priveleges将引用这个填充列表。

+0

另外..向您展示可变与不可变对象之间的区别,继续并更改列表“bertrand_priveleges”中的一项,然后再次调用bertrand.priveleges.show_priveleges()。 – Solaxun