Correct Way to Write in Python

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sat Aug 3 04:20:41 EDT 2013


On Fri, 02 Aug 2013 23:18:47 -0700, punk.sagar wrote:

> Hi All,
> 
> Im new to Python. Im coming from C# background and want to learn Python.
> I was used to do following thing in C# in my previous experiences. I
> want to know how do I implement below example in Python. How these
> things are done in Python. 

I am not an expert on C#, but I'll try to translate the following code to 
Python.


> [code]
> public class Bank
> {
> 	
> 	public List<Customer> lstCustomers = new List<Customer>();
> 	private string micrcode;
> 	
> 	public void Bank()
> 	{
> 		customer
> 	}
> 
> }
> 
> public class Customer
> {
> 	private srting customername;
> 	public string CustomerName

Do you mean "private string" rather than "private srting"?


> 	{
> 		get { return customername; }
> 		set { customername = value; }
> 	}
> }
> 
> main()
> {
> 	Customer objCustomer = new Customer;
> 	objCustomer.CustomerName = "XYZ"
> 	
> 	Bank objBank = new Bank();
> 	objBank.lstCustomer.Add(objCustomer);
> 	
> }
> [/code]


Here is a literally translation, as best as I can understand the C# code. 
(But note that this is not the best Python code.)


class Bank:
    def __init__(self):
        self.lstCustomers = []  # Empty list of customers.
        self._micrcode = ''  # Does this actually get used?

class Customer:
    def __init__(self):
        self._customername = ''

    @property
    def CustomerName(self):
        return self._customername

    @CustomerName.setter
    def CustomerName(self, value):
        if not instance(value, str):
            raise TypeError('names must be strings')
        self._customername = value


if __name__ == '__main__':
    # Running as a script, call the main function.
    objCustomer = Customer()
    objCustomer.CustomerName = "XYZ"

    objBank = Bank()
    objBank.lstCustomers.append(objCustomer)



But this isn't how I would write it in Python. For starters, our naming 
conventions are different. Everything in Python is an object, even simple 
types like ints and strings, and even classes, so it isn't meaningful to 
prefix instances with "obj".

We tend to avoid anything which even vaguely looks like Hungarian 
Notation, so "lstCustomer" is right out. Instead, we use plural for 
collections (lists, sets, dicts, whatever) of things, and singular for 
individual instances.

Also, while we can use the "property" decorator to make computed 
attributes, we very rarely do just to enforce private/public variables. 
Our philosophy is, if you want to shoot yourself in the foot, we're not 
going to stop you. (People spend far too much time trying to work around 
private names in other languages for Python to spend too much effort in 
this area.) Instead, we have "private by convention": names starting with 
a single underscore are "private", so don't touch them, and if you do, 
you have nobody but yourself to blame when you shoot yourself in the foot.

Similarly, the language doesn't spend much time enforcing type 
restrictions. Python is a dynamic language, and type restrictions go 
against that philosophy. If you have a good reason to put a non-string as 
the customer name, you can do so, but don't come crying to me if you 
break your code. So here is how I would write the above:



class Bank:
    def __init__(self):
        self.customers = []
        self._micrcode = ''  # Does this actually get used?

class Customer:
    def __init__(self, name):
        # This type-check is optional.
        if not instance(name, str):
            raise TypeError('names must be strings')
        self.name = name


if __name__ == '__main__':
    # Running as a script, call the main function.
    customer = Customer("XYX")

    bank = Bank()
    bank.customers.append(customer)


The above is still not what I call professional quality -- no doc strings 
(documentation), and the bank doesn't actually do anything, but it's a 
start.


-- 
Steven



More information about the Python-list mailing list